Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8051641

Africa/Casablanca transitions is incorrectly calculated starting from 2027

    Details

    • Subcomponent:
    • Resolved In Build:
      b44
    • CPU:
      generic
    • OS:
      generic
    • Verification:
      Verified

      Backports

        Description

        The 'sun/util/calendar/zi/TestZoneInfo310.java' test failures were observed during latest tzdata2014e integration into JDK9.
        The first failure is related to the internal representation of the '24:00' value. The JSR310 implementation treats this value as a 'day+1 00:00' value.
        Test fails with such error:
            sun/util/calendar/zi/TestZoneInfo310.java TZ failure:
               stz=java.util.SimpleTimeZone[id=ART,offset=7200000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=3,startDay=-1,startDayOfWeek=6,startTime=0,startTimeMode=1,endMode=2,endMonth=8,endDay=-1,endDayOfWeek=6,endTime=0,endTimeMode=0]
              stz0=java.util.SimpleTimeZone[id=ART,offset=7200000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=3,startDay=-1,startDayOfWeek=6,startTime=0,startTimeMode=1,endMode=2,endMonth=8,endDay=-1,endDayOfWeek=5,endTime=86400000,endTimeMode=0]
        The workaround already exists in JSR310 code for similar entries and this failure will be resolved in similar way as part of tzdata2014e update (see JDK-8049343 for details).

        Second failure can be observed after first problem is fixed. The Africa/Casablanca transitions is incorrectly calculated starting from 2027:
        Africa/Casablanca : Africa/Casablanca
        offset=0,dstSavings=0,useDaylight=false,transitions=83,offsets=3,checksum=-918774076,gmtChanged=false
        [NG]offset=0,dstSavings=3600000,useDaylight=false,transitions=103,offsets=3,checksum=450727553,gmtChanged=false
            -------------
            (NG) Different trans size :83, 103

        The full test output is attached for this failure is attached.

          Issue Links

            Activity

            Hide
            aefimov Aleksej Efimov added a comment -
            'sun/util/calendar/zi/TestZoneInfo310.java' test was added to the ProblemList.txt as part of JDK-8057747. When this problem will be resolved - the test should be removed from the list.
            Show
            aefimov Aleksej Efimov added a comment - 'sun/util/calendar/zi/TestZoneInfo310.java' test was added to the ProblemList.txt as part of JDK-8057747 . When this problem will be resolved - the test should be removed from the list.
            Hide
            aefimov Aleksej Efimov added a comment -
            It looks like, that according to debugging of ZoneInfoFile class the following tzdb snippet triggers an error in JSR310 implementation:
            Rule Morocco 2026 max - Mar lastSun 2:00 1:00 S
            Rule Morocco 2035 only - Oct 27 3:00 0 -
            Rule Morocco 2036 only - Oct 18 3:00 0 -
            Rule Morocco 2037 only - Oct 10 3:00 0 -

            Last three saving instant transitions rules doesn't observed in the tzdb.dat after deserialization by ZoneInfoFile class. The last transition year returned by ZoneInfoFile.getYear function returns 2027. If the max rule "Rule Morocco 2026 max - Mar lastSun 2:00 1:00 S" is changed to 2025 then the 2026 last year value is returned.
            Probably the issue can be located in build/tools/tzdb classes.
            Show
            aefimov Aleksej Efimov added a comment - It looks like, that according to debugging of ZoneInfoFile class the following tzdb snippet triggers an error in JSR310 implementation: Rule Morocco 2026 max - Mar lastSun 2:00 1:00 S Rule Morocco 2035 only - Oct 27 3:00 0 - Rule Morocco 2036 only - Oct 18 3:00 0 - Rule Morocco 2037 only - Oct 10 3:00 0 - Last three saving instant transitions rules doesn't observed in the tzdb.dat after deserialization by ZoneInfoFile class. The last transition year returned by ZoneInfoFile.getYear function returns 2027. If the max rule "Rule Morocco 2026 max - Mar lastSun 2:00 1:00 S" is changed to 2025 then the 2026 last year value is returned. Probably the issue can be located in build/tools/tzdb classes.
            Hide
            aefimov Aleksej Efimov added a comment -
            The debug output from build.tools.tzdb.ZoneRules shows that the last three saving instant transitions are ignored for some reason:
            0: 1913-10-26 03:00
            1: 1939-09-12 03:00
            2: 1939-11-19 02:00
            3: 1940-02-25 03:00
            4: 1945-11-18 02:00
            5: 1950-06-11 03:00
            6: 1950-10-29 02:00
            7: 1967-06-03 15:00
            8: 1967-10-01 02:00
            9: 1974-06-24 03:00
            10: 1974-09-01 02:00
            11: 1976-05-01 03:00
            12: 1976-08-01 02:00
            13: 1977-05-01 03:00
            14: 1977-09-28 02:00
            15: 1978-06-01 03:00
            16: 1978-08-04 02:00
            17: 1984-03-16 03:00
            18: 1986-01-01 02:00
            19: 2008-06-01 04:00
            20: 2008-09-01 03:00
            21: 2009-06-01 04:00
            22: 2009-08-21 03:00
            23: 2010-05-02 04:00
            24: 2010-08-08 03:00
            25: 2011-04-03 04:00
            26: 2011-07-31 03:00
            27: 2012-04-29 06:00
            28: 2012-07-20 06:00
            29: 2012-08-20 06:00
            30: 2012-09-30 06:00
            31: 2013-04-28 06:00
            32: 2013-07-07 06:00
            33: 2013-08-10 06:00
            34: 2013-10-27 06:00
            35: 2014-03-30 06:00
            36: 2014-06-28 06:00
            37: 2014-08-02 06:00
            38: 2014-10-26 05:00
            39: 2015-03-29 05:00
            40: 2015-06-13 05:00
            41: 2015-07-18 05:00
            42: 2015-10-25 05:00
            43: 2016-03-27 05:00
            44: 2016-06-04 05:00
            45: 2016-07-09 05:00
            46: 2016-10-30 05:00
            47: 2017-03-26 05:00
            48: 2017-05-20 05:00
            49: 2017-07-01 05:00
            50: 2017-10-29 05:00
            51: 2018-03-25 05:00
            52: 2018-05-12 05:00
            53: 2018-06-16 05:00
            54: 2018-10-28 05:00
            55: 2019-03-31 05:00
            56: 2019-05-04 05:00
            57: 2019-06-08 05:00
            58: 2019-10-27 05:00
            59: 2020-03-29 05:00
            60: 2020-04-18 05:00
            61: 2020-05-30 05:00
            62: 2020-10-25 05:00
            63: 2021-03-28 05:00
            64: 2021-04-10 05:00
            65: 2021-05-15 05:00
            66: 2021-10-31 05:00
            67: 2022-03-27 05:00
            68: 2022-04-02 05:00
            69: 2022-05-07 05:00
            70: 2022-10-30 05:00
            71: 2023-04-22 05:00
            72: 2023-10-29 05:00
            73: 2024-04-13 05:00
            74: 2024-10-27 05:00
            75: 2025-04-05 05:00
            76: 2025-10-26 05:00
            77: 2026-03-29 05:00
            78: 2026-10-25 05:00
            79: 2027-03-28 05:00
            80: 2027-10-31 05:00
            standardTransitions:
            0: 1913-10-26 03:00
            1: 1984-03-16 03:00
            2: 1986-01-01 02:00
            Show
            aefimov Aleksej Efimov added a comment - The debug output from build.tools.tzdb.ZoneRules shows that the last three saving instant transitions are ignored for some reason: 0: 1913-10-26 03:00 1: 1939-09-12 03:00 2: 1939-11-19 02:00 3: 1940-02-25 03:00 4: 1945-11-18 02:00 5: 1950-06-11 03:00 6: 1950-10-29 02:00 7: 1967-06-03 15:00 8: 1967-10-01 02:00 9: 1974-06-24 03:00 10: 1974-09-01 02:00 11: 1976-05-01 03:00 12: 1976-08-01 02:00 13: 1977-05-01 03:00 14: 1977-09-28 02:00 15: 1978-06-01 03:00 16: 1978-08-04 02:00 17: 1984-03-16 03:00 18: 1986-01-01 02:00 19: 2008-06-01 04:00 20: 2008-09-01 03:00 21: 2009-06-01 04:00 22: 2009-08-21 03:00 23: 2010-05-02 04:00 24: 2010-08-08 03:00 25: 2011-04-03 04:00 26: 2011-07-31 03:00 27: 2012-04-29 06:00 28: 2012-07-20 06:00 29: 2012-08-20 06:00 30: 2012-09-30 06:00 31: 2013-04-28 06:00 32: 2013-07-07 06:00 33: 2013-08-10 06:00 34: 2013-10-27 06:00 35: 2014-03-30 06:00 36: 2014-06-28 06:00 37: 2014-08-02 06:00 38: 2014-10-26 05:00 39: 2015-03-29 05:00 40: 2015-06-13 05:00 41: 2015-07-18 05:00 42: 2015-10-25 05:00 43: 2016-03-27 05:00 44: 2016-06-04 05:00 45: 2016-07-09 05:00 46: 2016-10-30 05:00 47: 2017-03-26 05:00 48: 2017-05-20 05:00 49: 2017-07-01 05:00 50: 2017-10-29 05:00 51: 2018-03-25 05:00 52: 2018-05-12 05:00 53: 2018-06-16 05:00 54: 2018-10-28 05:00 55: 2019-03-31 05:00 56: 2019-05-04 05:00 57: 2019-06-08 05:00 58: 2019-10-27 05:00 59: 2020-03-29 05:00 60: 2020-04-18 05:00 61: 2020-05-30 05:00 62: 2020-10-25 05:00 63: 2021-03-28 05:00 64: 2021-04-10 05:00 65: 2021-05-15 05:00 66: 2021-10-31 05:00 67: 2022-03-27 05:00 68: 2022-04-02 05:00 69: 2022-05-07 05:00 70: 2022-10-30 05:00 71: 2023-04-22 05:00 72: 2023-10-29 05:00 73: 2024-04-13 05:00 74: 2024-10-27 05:00 75: 2025-04-05 05:00 76: 2025-10-26 05:00 77: 2026-03-29 05:00 78: 2026-10-25 05:00 79: 2027-03-28 05:00 80: 2027-10-31 05:00 standardTransitions: 0: 1913-10-26 03:00 1: 1984-03-16 03:00 2: 1986-01-01 02:00
            Hide
            aefimov Aleksej Efimov added a comment -
            The root cause of the problem is the following:
            The TzdbZoneRulesProvider populates the last rules till the most latest start year of last rule + 1. For current example it is 2027:
                Rule Morocco 2013 max - Oct lastSun 3:00 0 -
                Rule Morocco 2014 2022 - Mar lastSun 2:00 1:00 S
                ...
                Rule Morocco 2026 max - Mar lastSun 2:00 1:00 S <--- The latest start year
                Rule Morocco 2035 only - Oct 27 3:00 0 -
                Rule Morocco 2036 only - Oct 18 3:00 0 -
                Rule Morocco 2037 only - Oct 10 3:00 0 -

            For this concrete example the latest transition calculated and saved to transitions list (not lasttransitions) is:
            31 October 2027 3:00 (generated by Rule Morocco 2013 max - Oct lastSun).
            Later in the code the instant transitions are filtered by such code:
                if (trule.isTransition(savings)) {
            Because the 'max' last rules weren't transformed to sequence of instant transitions until the last year = 2037 the three last instant transitions in current example were ignored because they have the same offset = '3:00'. And because of that these rules from tzdb didn't make a way to serialized transitions list in tzdb.dat:
                Rule Morocco 2035 only - Oct 27 3:00 0 -
                Rule Morocco 2036 only - Oct 18 3:00 0 -
                Rule Morocco 2037 only - Oct 10 3:00 0 -

            And it causes such tests failures:
                              2035-10-28T03:00 [utc=2077149600 raw=1e39fc39900, offset=0/Z, saving=0]
                (NG) 2035-10-27T03:00 [utc=2077063200 raw=1e39a9d3d00, offset=0/Z, saving=0]
                        -----
                              2036-03-30T02:00 [utc=2090455200 raw=1e6b8d6f100, offset=3600/+01:00, saving=3600]
                (OK) 2036-03-30T02:00 [utc=2090455200 raw=1e6b8d6f100, offset=3600/+01:00, saving=3600]
                        -----
                              2036-10-26T03:00 [utc=2108599200 raw=1eaf24e6900, offset=0/Z, saving=0]
                (NG) 2036-10-18T03:00 [utc=2107908000 raw=1eac91b8900, offset=0/Z, saving=0]
                        -----
                              2037-03-29T02:00 [utc=2121904800 raw=1ee0b61c100, offset=3600/+01:00, saving=3600]
                (OK) 2037-03-29T02:00 [utc=2121904800 raw=1ee0b61c100, offset=3600/+01:00, saving=3600]
                        -----
                              2037-10-25T03:00 [utc=2140048800 raw=1f244d93900, offset=0/Z, saving=0]
                (NG) 2037-10-10T03:00 [utc=2138752800 raw=1f1f799d500, offset=0/Z, saving=0]
            Show
            aefimov Aleksej Efimov added a comment - The root cause of the problem is the following: The TzdbZoneRulesProvider populates the last rules till the most latest start year of last rule + 1. For current example it is 2027:     Rule Morocco 2013 max - Oct lastSun 3:00 0 -     Rule Morocco 2014 2022 - Mar lastSun 2:00 1:00 S     ...     Rule Morocco 2026 max - Mar lastSun 2:00 1:00 S <--- The latest start year     Rule Morocco 2035 only - Oct 27 3:00 0 -     Rule Morocco 2036 only - Oct 18 3:00 0 -     Rule Morocco 2037 only - Oct 10 3:00 0 - For this concrete example the latest transition calculated and saved to transitions list (not lasttransitions) is: 31 October 2027 3:00 (generated by Rule Morocco 2013 max - Oct lastSun). Later in the code the instant transitions are filtered by such code:     if (trule.isTransition(savings)) { Because the 'max' last rules weren't transformed to sequence of instant transitions until the last year = 2037 the three last instant transitions in current example were ignored because they have the same offset = '3:00'. And because of that these rules from tzdb didn't make a way to serialized transitions list in tzdb.dat:     Rule Morocco 2035 only - Oct 27 3:00 0 -     Rule Morocco 2036 only - Oct 18 3:00 0 -     Rule Morocco 2037 only - Oct 10 3:00 0 - And it causes such tests failures:                   2035-10-28T03:00 [utc=2077149600 raw=1e39fc39900, offset=0/Z, saving=0]     (NG) 2035-10-27T03:00 [utc=2077063200 raw=1e39a9d3d00, offset=0/Z, saving=0]             -----                   2036-03-30T02:00 [utc=2090455200 raw=1e6b8d6f100, offset=3600/+01:00, saving=3600]     (OK) 2036-03-30T02:00 [utc=2090455200 raw=1e6b8d6f100, offset=3600/+01:00, saving=3600]             -----                   2036-10-26T03:00 [utc=2108599200 raw=1eaf24e6900, offset=0/Z, saving=0]     (NG) 2036-10-18T03:00 [utc=2107908000 raw=1eac91b8900, offset=0/Z, saving=0]             -----                   2037-03-29T02:00 [utc=2121904800 raw=1ee0b61c100, offset=3600/+01:00, saving=3600]     (OK) 2037-03-29T02:00 [utc=2121904800 raw=1ee0b61c100, offset=3600/+01:00, saving=3600]             -----                   2037-10-25T03:00 [utc=2140048800 raw=1f244d93900, offset=0/Z, saving=0]     (NG) 2037-10-10T03:00 [utc=2138752800 raw=1f1f799d500, offset=0/Z, saving=0]
            Hide
            aefimov Aleksej Efimov added a comment -
            The following modification helps to solve the Casablanca error:
            @@ -790,9 +814,35 @@
                                 }
                                 Collections.sort(lastRules);
                             }
            +
                             // sort the merged rules
                             Collections.sort(trules);
             
            + //Check if there is an instant rules inside a range of last rules
            + int applyLastRulesTill = -1;
            + for (TransRule rule : trules) {
            + if (lastRules.size()>0 && rule.year > lastRulesStartYear && rule.year > applyLastRulesTill)
            + applyLastRulesTill = rule.year;
            + }
            +
            + for (TransRule rule : lastRules) {
            + int year = rule.year;
            + while (year <= applyLastRulesTill) {
            + TransRule t = new TransRule(year, rule.rule);
            + trules.add(t);
            + year++;
            + }
            + rule.year = lastRulesStartYear;
            + rule.ldt = rule.rule.toDateTime(year);
            + rule.ldtSecs = rule.ldt.toEpochSecond(ZoneOffset.UTC);
            + }
            + if (applyLastRulesTill == 2037) {
            + lastRules.clear();
            + }
            + Collections.sort(trules);
            + // End of checking instant transitions that are coming after lastRules transitions

            But the test is still broken:
            Africa/Casablanca : Africa/Casablanca
                offset=0,dstSavings=3600000,useDaylight=true,transitions=102,offsets=3,checksum=1584984945,gmtChanged=false
            [NG]offset=0,dstSavings=3600000,useDaylight=true,transitions=103,offsets=3,checksum=450727553,gmtChanged=false
                -------------
                (NG) Different trans size :102, 103

            This is caused by Timezone.java class implementation that is a part of test classes: This class doesn't optimize the last one transition:
            for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one
            if (offsets.get(i) == offsets.get(i+1)
                            && dstOffsets.get(i) == dstOffsets.get(i+1)) {
                            transitions.remove(i+1);
                            offsets.remove(i+1);
                            dstOffsets.remove(i+1);
                            i--;
            }
            Show
            aefimov Aleksej Efimov added a comment - The following modification helps to solve the Casablanca error: @@ -790,9 +814,35 @@                      }                      Collections.sort(lastRules);                  } +                  // sort the merged rules                  Collections.sort(trules);   + //Check if there is an instant rules inside a range of last rules + int applyLastRulesTill = -1; + for (TransRule rule : trules) { + if (lastRules.size()>0 && rule.year > lastRulesStartYear && rule.year > applyLastRulesTill) + applyLastRulesTill = rule.year; + } + + for (TransRule rule : lastRules) { + int year = rule.year; + while (year <= applyLastRulesTill) { + TransRule t = new TransRule(year, rule.rule); + trules.add(t); + year++; + } + rule.year = lastRulesStartYear; + rule.ldt = rule.rule.toDateTime(year); + rule.ldtSecs = rule.ldt.toEpochSecond(ZoneOffset.UTC); + } + if (applyLastRulesTill == 2037) { + lastRules.clear(); + } + Collections.sort(trules); + // End of checking instant transitions that are coming after lastRules transitions But the test is still broken: Africa/Casablanca : Africa/Casablanca     offset=0,dstSavings=3600000,useDaylight=true,transitions=102,offsets=3,checksum=1584984945,gmtChanged=false [NG]offset=0,dstSavings=3600000,useDaylight=true,transitions=103,offsets=3,checksum=450727553,gmtChanged=false     -------------     (NG) Different trans size :102, 103 This is caused by Timezone.java class implementation that is a part of test classes: This class doesn't optimize the last one transition: for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one if (offsets.get(i) == offsets.get(i+1)                 && dstOffsets.get(i) == dstOffsets.get(i+1)) {                 transitions.remove(i+1);                 offsets.remove(i+1);                 dstOffsets.remove(i+1);                 i--; }
            Hide
            hgupdate HG Updates added a comment -
            URL: http://hg.openjdk.java.net/jdk9/dev/jdk/rev/8bb2d5d056bf
            User: aefimov
            Date: 2014-12-16 21:05:57 +0000
            Show
            hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/dev/jdk/rev/8bb2d5d056bf User: aefimov Date: 2014-12-16 21:05:57 +0000
            Hide
            rcalnan Roger Calnan added a comment -
            Defer request as the backport from 9 is proving complicated. Issue is only relevant for dates beyond 2027
            Show
            rcalnan Roger Calnan added a comment - Defer request as the backport from 9 is proving complicated. Issue is only relevant for dates beyond 2027
            Hide
            hgupdate HG Updates added a comment -
            URL: http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/8bb2d5d056bf
            User: lana
            Date: 2014-12-23 22:27:55 +0000
            Show
            hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/8bb2d5d056bf User: lana Date: 2014-12-23 22:27:55 +0000
            Hide
            idergali Ilya Dergalin (Inactive) added a comment -
            SQE is ok to defer from 8u40.
            Show
            idergali Ilya Dergalin (Inactive) added a comment - SQE is ok to defer from 8u40.

              People

              • Assignee:
                aefimov Aleksej Efimov
                Reporter:
                aefimov Aleksej Efimov
              • Votes:
                0 Vote for this issue
                Watchers:
                6 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: