Why is January 1 being reported as the last week of the previous year?


A customer (via the customer liaison) reported a problem that occurred when their program was run in Germany.

Ah, those pesky Germans. Always causing trouble.

In Germany, we find that the week numbers are wrong. For example, for the date January 1, 2005, the Get­Locale­Info function reports FIRST­DAY­OF­WEEK as 53 instead of the expected value of 1. The attached program demonstrates the issue.

The customer wants to know if there is anything we can do so we get the correct result. We saw the Set­Locale­Info function but weren't sure if it can be used to get the English calendar on a German system, or what unintended consequences there may be.

using System;
using System.Globalization;

class Program
{
  static void RunScenario()
  {
    DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
    Calendar cal = dfi.Calendar;

    DateTime date = new DateTime(2005, 1, 1);
    int weekOfYear = cal.GetWeekOfYear(date, dfi.CalendarWeekRule,
                                       dfi.FirstDayOfWeek);
    Console.WriteLine("{0:d} is week number {1}", date, weekOfYear);
  }

  static void Main()
  {
    RunScenario();

    System.Threading.Thread.
    CurrentThread.CurrentCulture = new CultureInfo("da-DK");
    RunScenario();
  }
}

One thing I noticed was that it wasn't the Germans causing trouble at all. It's the Danes!

    ... new CultureInfo("da-DK");

So your frustration is misdirected. You should be upset at those pesky Danes.

But the first thing I noticed is that the question makes no sense. The FIRST­DAY­OF­WEEK is an integer in the range 0 through 6, where 0 means Monday, and 6 means Sunday. It never returns 53. What's more, the Get­Locale­Info function is never called by this program.

So let's ignore the stated question and try to infer the question from the code. The code prints the week number for January 1, 2005, according to US-English and Danish rules. For US-English, it returns week 1, and for Denmark, it returns week 53.

This is hardly surprising, because if you play around in the Immediate window, or just add some more Write­Line statements, you'll see that the US-English and Danish locales have different calendar preferences:

Property US-English Danish
First­Day­Of­Week Sunday Monday
Calendar­Week­Rule First­Day First­Four­Day­Week

How did I know to look at those properties? Because those are the properties that the program itself passes to the Get­Week­Of­Year function!

Denmark starts the week on Monday. It follows the rule that Week 1 of the year is the first week with at least four days from that year. And January 1, 2005 was a Saturday. This means that the week containing January 1, 2005 has only two days from 2005. That's not enough, so the the first week of the year begins on January 3, 2005. January 1, 2005 is considered to be part of the last week of 2004, which is week number 53.

Therefore, the value of 53 is correct. If you want Denmark to follow week-numbering rules consistent with the United States, you will need to take it up with the Folketing, and possibly the European Parliament.

Now, if you decide that you want to show week numbers according to the United States convention even to people who did nothing wrong aside from happening to live in a country with the wrong week numbering rules, you can just pass your custom week numbering rules to the Get­Week­Of­Year function.

    int weekOfYear = cal.GetWeekOfYear(date,
                        CalendarWeekRule.FirstDay,
                        DayOfWeek.Sunday);

Don't change the system locale; that is trying to apply a global solution to a local problem.

Mind you, your local solution is going to make everybody in Denmark say, "How come your program gets all the week numbers wrong?"

Bonus reading: ISO 8601 Week of Year Format in Microsoft .NET.

Comments (43)
  1. acq says:

    I had to search why a January 1, 2005, a Saturday is a first week of 2005 in the US. Wikipedia to the rescue:

    "The US system has weeks from Sunday through Saturday, and partial weeks at the beginning and the end of the year, i.e. always 53 weeks."

    Does it mean that the same week around the 1 January has *two* week numbers at the same time?

  2. Nicholas says:

    "Don't change the system locale; that is trying to apply a global solution to a local problem."

    Also, make sure your program doesn't mention the war.

  3. Smithers says:

    "always 53 weeks"

    My approximate train of thought: Surely it can't be *always* 53… Each year lasts 52*7+1 days, so if a year begins on ${foo}day of week 1, it ends on, huh, ${foo}day of week 53. I guess that works whatever day of the week it starts on.

    Ah, wait! That doesn't work on leap years though! If January 1st is Saturday of week 1, then December 30th is Saturday of week 53 and December 31st is Sunday of week 54. Point to Smithers. Wikipedia is wrong roughly once every 28 years. Actually, I suppose that's a lot better than most articles.

    Seriously though, USA, why can't you let a week that's in two years at once just be one week? Also FirstDayOfWeek=Sunday?? It's called the week*end*, it comes at the *end* of the week.

    [Like a rope or stick or soccer pitch, a week has two ends. There's the front end (Sunday) and the back end (Saturday). The difference is in the interpretation of the word "end". One interpretation is "not the beginning"; another is "extremity". And seriously, Europe. How can you say with a straight face that January 1, 2005 is week 53 of 2004? It's not even in 2004! -Raymond]
  4. Martijn says:

    "Does it mean that the same week around the 1 January has *two* week numbers at the same time?"

    It has two numbers, but not at the same time. The first part of the week is week 53, 2005, the second part is week 1, 2006.

  5. Sean says:

    @acq Not exactly. That week is instead treated as two separate partial weeks. So the part from January 1 to the end of the week is week 1, and the part from before January 1 is week 53 of the previous year. So each day is still part of exactly one week of the year.

  6. 12BitSlab says:

    I lost track of the number of different systems/languages/environments I have worked with over the years.  Date/Time stuff always tends to be very ugly.  .Net does as good of a job as any environment I have worked with of making date/time stuff easy for the average developer.

  7. Cesar says:

    As long as the month number does NOT range from 0 to 11, I'm happy.

  8. pc says:

    @Cesar:

    Surely you're not thinking of Java's Calendar classes? Their months don't range from 0 to 11, but from 0 to 12!

    docs.oracle.com/…/Calendar.html

    *sigh*

  9. Johan says:

    There are more countries in the world than the US.

    Metric system FTW!!

  10. DWalker says:

    "Like a rope or stick or soccer pitch, a week has two ends."  I never thought of it that way!  Although for a week, one of the days is "the beginning", and the other is "the end".  

    Dates are hard.

  11. creaothceann says:

    @DWalker:

    That's probably why most of us are single.

  12. @pc: To be fair, Java now has a pretty sane datetime system in the java.time package.  Granted, it's more or less a carbon copy of Joda, but that's not really a bad thing.

  13. viila says:

    @Raymond "Like a rope or stick or soccer pitch, a week has two ends. The difference is in the interpretation of the word "end"."

    Many other languages are not ambiguous about it. For example Finnish and Swedish (and I'd imagine Danish as well given how close it is to Swedish). In Finnish it's "viikonloppu" where the "loppu" can only mean finishing/conclusion of something. Similarly Swedish "veckoslut".

    Vice versa, the end of a soccer pitch in Finnish would be "pääty". (And in Swedish, I think "ände".)

  14. Henri Hein says:

    @Nicholas: +1

    @creaothceann: +1

    I am one of those pesky Danes and grew up with the week numbering scheme.  Other than its succinctness, I had difficulties understanding its advantage.  You hear stuff like "the school year starts in week 31," "we will meet again in week 42."  You can get the approximate month by dividing by 4, but to get more granular, you have to consult a calendar or be Jeffrey Ma.  However, that the last week should be numbered after its Monday, since that is when the week officially starts, always did make sense.  

  15. Simon says:

    Yes, the *new* Java 8 date/time framework is awesome… a few quirks, but easily the best date API that I've ever encountered. Still not fully integrated into the enterprise frameworks, unfortunately, but still vastly superior to the old date/calendar APIs…

  16. Brian says:

    A couple of things:

    a) For the most part "week number" is almost never used in the US or Canada.  Some accounting systems use it, but no one thinks about it at all

    b) @Johan: Metric? For dates?  The only metric-ish attempts at a date system that I know of was during the French Revolution and its aftermath (the "French Republican Calendar" according to Wikipedia).  It lasted about 12 years.  I think we should all move to the Hobbit calendar.  That's one that makes a lot of sense.

    c) Dates are easier than times.  Getting shift reports right for shifts that may or may not span the end of a day and that properly compensate for daylight saving time, etc. is amazingly complex.

  17. Zack says:

    I was so very much expecting the punchline to be about how YYYY-01-01T00:00:00Z can map to YYYY or YYYY-1 depending on which timezone you're in.

    I'm not sure whether this is better, or worse.

  18. bzakharin says:

    There was a proposal by the "World Decimal Time Society" for completely metric timekeeping discussed in Popular Mechanics in the mid 90's sometime (1996 most likely). It included 10 months a year, 10 days in a week (3 weekends), time of day divided into 1000 units called tims (which would replace minutes) and millitims could be used for more precise timekeeping. The year number would approximate the age of the earth. The system would go into effect on March 21 4600002000, or 000 for short (maybe 2000 would have worked too).

    Found it, May 1996: books.google.com/books

  19. Douglas says:

    I'm still waiting for Jon Skeet to poke his head in here and comment :)

  20. Dave says:

    >It's the Danes!

    Ah, those Swedes…

    Sorry, Danes.  Danes.  I meant Danes when I said Swedes.

  21. cheong00 says:

    For some reason, I always use CultureInfo.InvariantCulture on any applicable DateTime handling code.

    Any by the way, the effect of

  22. Lawrence says:

    Huh, for some reason made it this far in life without knowing the US starts weeks on Sundays. How strange! In my country, Sunday along with Saturday) counts as part of the "weekend" – a new week starts on Monday.

  23. Cube 8 says:

    Sunday or Monday? http://www.cjvlang.com/…/SunMon.html

    Also, ISO 8601 states that Monday is the first day of week: en.wikipedia.org/…/Sunday

  24. Marcel says:

    @Henri Hein: "However, that the last week should be numbered after its Monday, since that is when the week officially starts, always did make sense.". But that's not how it works. Not in Germany, and according to the article, also not in Denmark. It's numbered after its Thursday. So if January 1st is a Thursday, then December 31th is already part of week 1 of the following year.

    At work we use a libc from an American company and I had to implement strftime myself because the existing one doesn't support ISO week numbers…

  25. Stephen Johnston says:

    Bread has two ends, as does a car and a strong. This is why the weekend can be both at the beginning and at.. the end.

  26. Thomas Stockschläder says:

    The week that contains January 4th is always the first week of the year, because it consists *mainly* (atleast 4/7 days) of dates in January.

  27. frenchguy says:

    @Brian: My guess for why the revolutionary calendar failed (in addition to force of habit) is that it had only 1 day in 10 as a day of rest, compared to the previous 1 day in 7. If, like the decimal calendar Boris mentioned, it had tried to preserve the existing balance between work days and rest days (by having an extra half-day of rest), I'm sure it would have lasted longer.

  28. hyperman says:

    If you're interested, I dumped the Java Locale information to see what country does what. Now I'm wondering what's going on in Malta.

    day 7 is saterday, day 6 is friday, btw

    1 jan 2005 is week 1, day 6 in Japan, Thailand

    1 jan 2005 is week 1, day 7 in Albania, Algeria, Argentina, Australia, Bahrain, Belarus, Bolivia, Bosnia and Herzegovina, Brazil, Bulgaria, Canada, Chile, China, Colombia, Costa Rica, Croatia, Cyprus, Dominican Republic, Ecuador, Egypt, El Salvador, Guatemala, Honduras, Hong Kong, Hungary, India, Indonesia, Iraq, Ireland, Israel, Japan, Jordan, Kuwait, Latvia, Lebanon, Libya, Macedonia, Malaysia, Mexico, Montenegro, Morocco, New Zealand, Nicaragua, Oman, Panama, Paraguay, Peru, Philippines, Puerto Rico, Qatar, Romania, Russia, Saudi Arabia, Serbia, Serbia and Montenegro, Singapore, Slovenia, South Africa, South Korea, Sudan, Syria, Taiwan, Tunisia, Turkey, Ukraine, United Arab Emirates, United States, Uruguay, Venezuela, Vietnam, Yemen

    1 jan 2005 is week 52, day 7 in Malta

    1 jan 2005 is week 53, day 7 in Austria, België, Czech Republic, Denmark, Estonia, Finland, France, Germany, Greece, Iceland, Ireland, Italy, Lithuania, Luxembourg, Nederland, Norway, Poland, Portugal, Slovakia, Spain, Sweden, Switzerland, United Kingdom

  29. Steve says:

    Just reading this thread minutes after discovering that an elderly third-party system that I'm attempting to interface with permits time values of 01/01/2015 24:00 …

  30. Jon Skeet says:

    As Douglas invited me in, so to speak… I find it somewhat amusing that .NET supports various kinds of week numbering, but not (quite) ISO-8601… whereas my Noda Time library supports ISO-8601 but no *other* week numbering schemes. At some point I might need to add a bit of BCL-compatible week numbering code. No-one's asked for it yet though.

  31. Jon Skeet says:

    @Steve: A value of 01/01/2015 24:00 is valid under ISO-8601, so you shouldn't think too badly of the system you're using.

    I've tried to work out how we could model that in the Noda Time API – currently we allow it to be parsed, but we don't retain the information – it parses to the exact same value as midnight at the start of January 2nd. That's unfortunate, but too many things become horrible when you view 24:00 as a valid time of day :(

  32. John Elliott says:

    The only place I've seen any sort of week numbering system used in the UK is in the tax calculation, where Week 1 is in April.

  33. Mike Collins says:

    If I remember correctly, isn't Denmark also the country where the list separator is a semi-colon?

    The Danes' "CSV" export caused me massive headaches with this a few years ago!

  34. @Mike Collins says:

    "isn't Denmark also the country where the list separator is a semi-colon"

    Also Germany (and others), because "," is already used as the decimal separator.

  35. Douglas says:

    What I find endlessly amusing is how amazingly, ridiculously complicated the division of time on Planet Earth is.

  36. boogaloo says:

    It's weird, but I guess they do this for working weeks.

    The majority of people don't work new years day so you ignore that and if January the 2nd is a Saturday or Sunday then that is the "weekend" so that gets added to week at the end of the previous year.

    I find this less annoying than people who say midnight on Monday, when they really mean 00:00 on Tuesday which is a full 24 hours later than the real midnight that occurs during Monday.

  37. Adam Rosenfield says:

    When I saw the title, my initial thought was "duh, ISO 8601 week numbers," in particular because 2015 is also one of those years that has 53 ISO weeks, and this was related to some things I was dealing with back in January.  I was intrigued to see the locale-dependent aspect of this, though.

  38. moo says:

    Map of the first day of the week around the world, for anyone interested:

    commons.wikimedia.org/…/File:First_Day_of_Week_World_Map.svg

  39. John Elliott: You may want to look at the UKHO as well then.  All of their chart and NP corrections are pegged to a week number; in fact it's the ISO 8601 week number (it's actually common to the entire industry).  I have an extension method at work that exists entirely to give me the ISO 8601 week number of a DateTime value.

  40. Alexa Lang says:

    @Cube 8: Unfortunately the page you link to mainly discusses the start of the week in Christianity and Judaism. All European pre-Christian sources (mostly etymological) let the week start on Monday, a practice which never really went away even when the Christian way was the official way. (Indeed, it seems likely that Constantine chose Sunday as the Christian Sabbath for pragmatical reasons. Some sources state that Sunday gradually took over from Sunday, but we haven't got enough information from the early period to tell.) Another thing that it glosses over is that the (often incomplete) adoption of the Sunday first system also took a lot of time, often centuries after Constantine and often had more to do with the celebration of Easter, which the site oddly completely fails to mention.

    The site claims that industrialisation killed the Sunday-first system, but that doesn't make a lot of sense. If at the time Sunday had been generally considered the start of the week then the week would have been generally considered to start and end with a day of rest, as in the United States. The term weekend originated because in northern England, where it was coined, at the time Monday was considered (if not necessarily officially) the start of the week. The origin of the word weekend also shows the two-ended week interpretation to be wrong, as it originated as a name of the part of week after offices closed on the last working day (originally Saturday noon) as a single time span. Note how the beginning of time spans is never named the end in English, or any of the Germanic and Romance languages I know, and that it was called ‘weekend’ from the outset, not ‘weekends’. Time spans just are fundamentally different from symmetrical things like ropes and pitches in that they can be traversed in only one direction, giving them a clear start and end.

  41. Alex Cohn says:

    @Cesar: here, the months are numbered 1-12 or 1-13, to make you happy. But note two extra facts: the year number increments between months #6 and #7; and when we have the 13th month (7 times in 19 years), it is "inserted" after month #11.

  42. DWalker says:

    Interesting that I usually think of Monday as "the beginning of the week", even though I am perfectly happy with my calendar (I'm in the US) showing Sunday on the left, Saturday on the right, and Monday-Friday in the middle of each row.

    "too many things become horrible when you view 24:00 as a valid time of day".  True.  We had a data supplier begin sending "2400" as a time-of-day string in a data field that was formatted to accept hhmm.  The program that parsed the data was old, and did not do a good job of cleaning the data before trying to insert into a SQL table (into a Time field).  Hilarity did not ensue.  The replacement code handles this.

  43. EMB says:

    @Lawrence In Brazil, people says weekend meaning Saturday and Sunday. But Sunday is the first day of week. Now, go figure.

Comments are closed.

Skip to main content