0

I am try to find a nice way to work out the week number from a non standard starting date. Week 1 shall contain the first Sunday in April. To calculate this, I just loop through the first 7 days in April til I find the first Sunday. Weeks will start on Sunday.

Normally I would attempt to solve this doing something like this:

numberOfDaysDifferenceBetweenEpoch / 7 % 52 + 1;

However about every 5 years it works out as there are 53 weeks in a year. Obviously the function above will not work if it happens to be a 53 week year. An easy solution would be just to make two functions, which take the modulus of 52 or 53 however I'm hoping there is a cleaner way of doing this. What would the best way to approach this problem?

Tom Dee
  • 2,516
  • 4
  • 17
  • 25
  • How big can "numberOfDaysDifferenceBetweenEpoch " be? What is the maximum value of this variable? – Lasse V. Karlsen Apr 10 '18 at 12:31
  • should check this: https://stackoverflow.com/questions/8808878/system-globalization-calendar-getweekofyear-returns-odd-results – Thowk Apr 10 '18 at 12:32
  • Greater then 366, so can span across several years from the initial first Sunday in April – Tom Dee Apr 10 '18 at 12:32
  • I don't think I really get what you're trying to do. Is it: you have a `DateTime` value and want to get the week number as if the weeks would always "restart" at the first sunday in april? If so, why not "simply" get the first sunday in april of the year of the value and determine if the value is before or after that date. If it's after, simply subtract that date from the value and divide the days by seven. If it's before, get the first sunday in april of the year before and subtract *that* from the value and divide the days by seven (... and add one in both cases)? – Corak Apr 10 '18 at 12:52
  • @Corak yes that's basically what I want. I wanted to try to avoid to recalculating the start of the year for every date and just base it off one starting date. But may just have to do it that way. – Tom Dee Apr 10 '18 at 13:21
  • 1
    @TomDee - you could keep a `Dictionary` and remember the first sunday in april for every year you already calculated it, if you feel like recalculating it "every time" might be a bottleneck. You could even pre-fill that dictionary if all your dates are in a known range. – Corak Apr 10 '18 at 13:28

1 Answers1

3

Here is one way that should work. You may want to optimise the GetEpochInYear method if you are using it frequently.

private static DateTime GetEpochInYear(int year)
{
    DateTime currentYearEpoch = new DateTime(year, 4, 1);
    while (currentYearEpoch.DayOfWeek != DayOfWeek.Sunday)
    {
        currentYearEpoch = currentYearEpoch.AddDays(1);
    }
    return currentYearEpoch;
}

private static int GetWeekNumber(DateTime dateOfInterest)
{
    DateTime currentYearEpoch = GetEpochInYear(dateOfInterest.Year);
    if (dateOfInterest < currentYearEpoch)
    {
        currentYearEpoch = GetEpochInYear(dateOfInterest.Year - 1);
    }            
    int days = (int)(dateOfInterest - currentYearEpoch).TotalDays;
    return (days / 7) +1;
}
Adam G
  • 1,283
  • 1
  • 6
  • 15