The Tale of Lost Moscow Time, or What Microsoft Guys Mistaken

    The other day, I regretfully discovered that the Windows operating system family contains incorrect information about Moscow time. It is noteworthy that the error has not yet been fixed, although it leaked into the system back in 2011. The consequences of the error will be shown using .NET, but this is true for all technologies that trust Windows data on time zones and time offsets.

    So, the time zone of Moscow is set on my car:

    We create the date 03/09/2014 10:00 in UTC. Then we translate it into Moscow time. As you know, now for Moscow the UTC + 04: 00 offset is valid all year round :

    var dt = new DateTime(2014, 3, 9, 10, 0, 0, DateTimeKind.Utc); //09.03.2014 10:00 UTC
    Console.WriteLine("UTC: {0},\nMoscow: {1}",dt, dt.ToLocalTime() );

    We get:
    UTC: 03/09/2014 10:00:00,
    Moscow: 03/09/2014 14:00:00

    Well, not bad. However, we will plunge a little deeper into the past. Prior to the cancellation of the clock for winter time, our country translated the clock hands twice a year. In winter, Moscow time had a shift of UTC + 03: 00, and in summer UTC + 04: 00.
    We repeat the operation for the date 09.03.2010 10:00 in UTC.

    var dt = new DateTime(2010, 3, 9, 10, 0, 0, DateTimeKind.Utc); //09.03.2010 10:00 UTC
    Console.WriteLine("UTC: {0},\nMoscow: {1}",dt, dt.ToLocalTime() );

    We get:
    UTC: 03/09/2010 10:00:00,
    Moscow: 03/09/2010 14:00:00

    Something is wrong. In March 2010, winter time was in effect, for which the offset should be +03: 00 hours, and not +04: 00. Similarly, for daylight saving time (June 2010):

    var dt = new DateTime(2010, 6, 9, 10, 0, 0, DateTimeKind.Utc);  //09.06.2010 10:00 UTC
    Console.WriteLine("UTC: {0},\nMoscow: {1}",dt, dt.ToLocalTime() );

    UTC: 06/09/2010 10:00:00,
    Moscow: 06/09/2010 15:00:00

    In the summer, the shift was +04: 00, but we got a shift of +05: 00, which was never in the Moscow time zone!

    What is the matter?

    Time zone information is stored in the Windows registry and updated with patches. Instead of using the tz database , which updates global time zone information (and which is used in * nix systems, BSD systems, and Mac OS X), Microsoft maintains its own database.

    To simplify it a bit, the information in it is stored like this. For the time zone, the base offset relative to UTC is indicated, then there is information about the transition to summer / winter time. It talks about when the transition is made and how the base offset changes. Prior to the cancellation of the switch to winter time, the following figures worked for Moscow:
    • Base Offset: UTC + 03: 00
    • Winter time = base offset
    • Summer time = base offset +01: 00

    After canceling the switch to winter time, hotfix came out , which was supposed to fix the year-round shift UTC + 04: 00 for Moscow. But there was an error. Instead of setting permanent daylight saving time, Microsoft changed the base offset from +03: 00 to +04: 00 and turned on permanent daylight saving time. But the fact is that Microsoft’s time zone database does not contain historical information about the change in the base offset. As a result, for dates before the summer of 2010, the following situation is obtained. When winter time is in effect, its shift coincides with the base. Before the patch was released, it was +03: 00, and now it has become +04: 00. When daylight saving time is in effect, it has an offset of +01: 00 relative to the base. Previously, it turned out +04: 00, and after the release of the patch it became +05: 00.

    After some time, this problemIt was noticed , and at Microsoft they prepared another hotfix , which was supposed to correct the current situation. However, installing it does not fix the problem.

    Currently, it has been experimentally found that the error is reproduced on Windows 7, Windows 8, as well as Windows Server 2008 R2. In the case of .NET, this problem can be solved by working with dates using the NodaTime library , which uses the tz database.

    Also popular now: