JDK-8051641 : Africa/Casablanca transitions is incorrectly calculated starting from 2027
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.time
  • Affected Version: 8u40,9
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2014-07-22
  • Updated: 2015-09-29
  • Resolved: 2014-12-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u60Fixed 9 b44Fixed
Related Reports
Relates :  
Relates :  
Relates :  
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.

Comments
SQE is ok to defer from 8u40.
24-12-2014

Defer request as the backport from 9 is proving complicated. Issue is only relevant for dates beyond 2027
22-12-2014

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--; }
09-12-2014

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]
09-12-2014

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
04-12-2014

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.
03-12-2014

'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.
08-09-2014