DateTime.Now.DayOfYear not behaving as expected, causing problems as a Random seed

584 Views Asked by At

I'm using the following method to get a random value from a list of IDs.

    private int GetRandomDateBasedSectorId(IEnumerable<int> sectorIds)
    {
        var randomSortTable = new Dictionary<int, int>();

        foreach (int id in sectorIds)
            randomSortTable[new Random(DateTime.Now.DayOfYear).Next()] = id;

        return randomSortTable.OrderBy(KVP => KVP.Key).Select(KVP => KVP.Value).FirstOrDefault();
    }

The reason I'm using DateTime.Now.DayOfYear as the seed is because I want to pick the same sectorId every time the method executes in a day, and the next day I'll pick a different random one.

This works to a degree, but it's not perfect. For example Yesterday morning and the night before it was consistently picking a single sector ID, then at some point yesterday it started picking a different sector ID, and today it's still using the same sector ID that it used yesterday afternoon.

I thought DateTime.Now.DayOfYear would change at midnight GMT (my current time-zone), but it doesn't seem to be.

Can somebody fill me in on if DateTime.Now.DayOfYear behaves differently than I expect it to? If so, is there a way for me to modify this so that I can ensure that it'll pick a new Sector ID from the list at midnight every day?

2

There are 2 best solutions below

0
On BEST ANSWER

Unless the day changes during the method call, you're always just going to be returning the last id in sectorIds. You'll be replacing the same key every time, because you're creating a new instance of Random (with the same seed) on each iteration. I don't think that's what you want...

It seems to me that a much simpler approach would be:

private int GetRandomDateBasedSectorId(IEnumerable<int> sectorIds)
{
    List<int> ids = sectorIds.ToList();
    Random rng = new Random(DateTime.Now.DayOfYear);
    return ids[rng.Next(ids.Count)];
}

This will pick the same element by position each time. Whether it actually returns the same sector ID will depend on whether the sectorIds sequence itself is stable.

0
On

I suggest that you do it like this:

int numberOfItems = randomSortTable.Count;
int index = (new Random(DateTime.Now.DayOfYear).Next()) % numberOfItems;
randomSortTable[index] = id;

Thanks Neelesh