Your weeks should be numbered
By , journalist and programmer

In the United States week numbers seem to be a rare phenomenon, I was told. In Europe the opposite is the case: almost everyone in business or politics uses them. Hence, calendars and schedulers are considered to be far from complete in case week numbers are missing. In other words: programmers who want to create scheduler-like software for the European market will surely not be successful if they omit the week number issue in their applications.

Is it a difficult matter? Not really, although things would be a lot easier if a year counted 364 days, making exactly 52 weeks. Like the year itself, week 1 would always start on the same day and date then. But unfortunately we have to deal with the fact that the first day of the first week is floating. It may even fall in December! Due to this 'irregularity' a year sometimes counts 53 week numbers.

Rules
To calculate correct week numbers, certain rules, set by the International Organization for Standardization (ISO), are to be followed. One of these rules states that Monday, not Sunday, is the first day of the week. Another important matter is how a week qualifies for Week Number One. Simply said: a year's first week is the week wherein the first Thursday of the year is falling. To put it in a somewhat different way: week number 1 labels the week that counts at least four January-days.

A few examples:
   In 2003, January 1 falls on a Wednesday and is part of week 1, because this week counts 5 January-days. The first day of this week, however, is not a January-day but Monday, December 30.
   Two years later, in 2005, January 1 (Saturday) and January 2 (Sunday) are part of week 53.
   In 2006 January 1 (Sunday) 'belongs' to week 52.

So far the rules. Now the programming stuff. Although calendar dates are not really the perfect data to do additions or substractions with, it is pretty easy to find or calculate the date that marks the beginning of the first week. The best way is to convert calendar dates to long-integer values first. I'm using a Julian-conversion for it, but there are different other ways that lead to Rome, as they say. If you would prefer any other method, for instance Microsoft's DateSerial or DateValue, feel free to alter that part of the coding.

Lower and upper bound
First of all we need to find the Julian Day Number (or DateSerial) for the first Thursday. The easiest way to do so is to take JDN for December 31 as a starting point and then repeatedly add 1 until the day of the week connected with this JDN appears to be 4 (= Thursday). By substracting 3 from this JDN, we get the Julian Day Number for the Monday that marks the beginning of week 1. We also need the JDN for the final day of the year's final week, which is the (Sun)day before the Monday of next year's first week. Actually, these 2 JDN's mark the lower and upper bound of the year's week counting system, respectively.

Before we're ready to compare, we need a third Julian Day Number (or DateValue), the one for the calendar date we want to connect with a week number and which parameters (year, month, day) were passed to the function. In respect with that specific JDN there are 3 possibilities:

  1. JDN-of-date is greater than the one we found for the upper bound
  2. JDN-of-date is less than the one we found for the lower bound
  3. JDN-of-date matches or lies in between the lower and upper bound
If either situation 1. or situation 2. occurs, in other words: if JDN-of-date is out of bounds, the date belongs either to the first week of next year or to the final week of previous year. Situation 1. is a piece of cake: the date falls in next year's week 1. No further calculations are necessary. Situation 2. is a bit more complicated. We're obviously dealing with the final week of the year before, but is it 52 or 53? The only way to find out is to replace the lower bound for year-of-date by the one for the year before.
Having done that, the rest of the calculation is the same for both, situation 2. and situation 3.: substract the lower bound JDN from JDN-of-date and (integer) divide the result by 7 to get the number of fully elapsed weeks so far. Finally add 1 for the 'going' week and there's your week number.

Here is the pseudo code for this routine:


  SELECT CASE AS LONG JDNOfDate
    CASE < LowerBound
      ' it is week 52 or 53, but which one?
      ' therefore we need week one of previous year as our reference
      LowerBound = WeekOne(year - 1)
    CASE > UpperBound
      ' there is only one possibility: week nbr 1
      FUNCTION = 1
      EXIT FUNCTION
  END SELECT
  FUNCTION = ((JDNOfDate - LowerBound) \ 7) + 1


Where to download?
   Click here to download the source code.
   Back to homepage

Copyright © 2000-2002: Egbert Zijlema
Failed to execute script '/cgi-bin/hidden.exe?weeknbr': Win32 Error Code = 2