Menu

#81 Libical produces incorrect TZ rules for Europe/Moscow

closed-fixed
nobody
recur (12)
5
2014-03-18
2011-11-02
No

Russia recently moved on to permanent DST, so there was no DST->STD transition in October.

However, libical thinks there was:

Using the following test program:

#include <libical/icaltimezone.h>
#include <stdio.h>

int main(int argc, char **argv)
{
icaltimezone *tz = icaltimezone_get_builtin_timezone (argv[1]);
icaltimezone_dump_changes (tz, 2012, stdout);
}

$ ./tztest Europe/Moscow | tail -5
Europe/Moscow 30 Oct 2010 23:00:00 +0300
Europe/Moscow 26 Mar 2011 23:00:00 +0400
Europe/Moscow 29 Oct 2011 23:00:00 +0300
Europe/Moscow 24 Mar 2012 23:00:00 +0400
Europe/Moscow 27 Oct 2012 23:00:00 +0300

zdump seems to get this right:

$zdump -c2010,2012 -v Europe/Moscow
Europe/Moscow -9223372036854775808 = NULL
Europe/Moscow -9223372036854689408 = NULL
Europe/Moscow Sat Mar 27 22:59:59 2010 UTC = Sun Mar 28 01:59:59 2010 MSK isdst=0 gmtoff=10800
Europe/Moscow Sat Mar 27 23:00:00 2010 UTC = Sun Mar 28 03:00:00 2010 MSD isdst=1 gmtoff=14400
Europe/Moscow Sat Oct 30 22:59:59 2010 UTC = Sun Oct 31 02:59:59 2010 MSD isdst=1 gmtoff=14400
Europe/Moscow Sat Oct 30 23:00:00 2010 UTC = Sun Oct 31 02:00:00 2010 MSK isdst=0 gmtoff=10800
Europe/Moscow Sat Mar 26 22:59:59 2011 UTC = Sun Mar 27 01:59:59 2011 MSK isdst=0 gmtoff=10800
Europe/Moscow Sat Mar 26 23:00:00 2011 UTC = Sun Mar 27 03:00:00 2011 MSK isdst=0 gmtoff=14400
Europe/Moscow 9223372036854689407 = NULL
Europe/Moscow 9223372036854775807 = NULL

It looks like the problem is in icaltz-util.c:find_transidx() There we assume that if there are daylight transitions in the timezone, we can just use the previous year's one as an indicator for the next. This is wrong in a zone like Europe/Moscow where the zone stopped in permanent DST

It looks like the fix should be to project the transitions forwards and use that to see if there is a DST transition in the current year (and don't add a DST RRULE if there aren't).

Discussion

  • Anonymous

    Anonymous - 2011-11-02

    The problem here is that we are using heuristics at all. Version 2 (since 2005) of the tz file binary format includes a string in the style of a POSIX $TZ environment variable, "for use in handling instants after the last transition time stored in the file". For example:
    $ strings /usr/share/zoneinfo/US/Pacific | tail -1
    PST8PDT,M3.2.0,M11.1.0
    $ strings /usr/share/zoneinfo/Europe/London | tail -1
    GMT0BST,M3.5.0/1,M10.5.0

    In the case of future recurrence we might have to infer the precise time-of-day for the transition from previous transitions, but the fact that there *is* future recurrence is explicitly specified and we should not have to guess.

    I don't want to see a "fix" which merely improves our guesswork. That seems like the wrong solution.

     

    Last edit: Anonymous 2013-09-26
  • James Bottomley

    James Bottomley - 2011-11-08

    Fix for the problem by making VTIMEZONE an exact mirror of the transition rules

     
  • James Bottomley

    James Bottomley - 2011-11-08

    Fix is attached for review. It makes the VTIMEZONE specifier an exact mirror of the transitions in the zone files, so it now uses absolute dates rather than trying to calculate a RRULE.

    This fixes the Europe/Moscow problem

     
  • Allen Winter

    Allen Winter - 2012-03-13

    with the current development version in svn, when I run your test program I get:

    $ ./tztest Europe/Moscow
    Europe/Moscow 26 Mar 1970 23:00:00 +0400

    Is that correct??

     
  • Allen Winter

    Allen Winter - 2012-06-23

    Thanks for the patch! seems to work great.

    committed in r1130

     
  • Allen Winter

    Allen Winter - 2012-06-23
    • status: open --> closed-fixed
     
  • Patrick Ohly

    Patrick Ohly - 2014-03-18

    I can't reproduce the original problem using the original, heuristic-based icaltz-util.c and tzdata 2013i-0wheezy1 on Debian Wheezy. I get the correct timezone component:

    BEGIN:VTIMEZONE
    TZID:/freeassociation.sourceforge.net/Tzfile/Europe/Moscow
    X-LIC-LOCATION:Europe/Moscow
    BEGIN:STANDARD
    TZNAME:MSK
    DTSTART:19700327T030000
    TZOFFSETFROM:+0400
    TZOFFSETTO:+0400
    END:STANDARD
    END:VTIMEZONE

    Just FYI. As mentioned in #95, the new code causes interoperability issues.

     

Log in to post a comment.