diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-02-01 11:12:23 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-02-01 11:12:23 +0000 |
commit | ade5d45aab1fc5e905515dc2ef9d5b572cb24295 (patch) | |
tree | b4c9e593412a7685f639838d403b581747d29738 | |
parent | c445130e0a7c2ec467fd585d5b9472f9b532ffa4 (diff) | |
parent | f62027d72f1f892db5a646f87de35c8bad8525e0 (diff) | |
download | timezone-platform-tools-34.0.0.tar.gz |
Snap for 9550355 from f62027d72f1f892db5a646f87de35c8bad8525e0 to sdk-releaseplatform-tools-34.0.1platform-tools-34.0.0platform-tools-33.0.4
Change-Id: I3f34e67668b27373c83e65037f8297fa3a4db64a
29 files changed, 505 insertions, 251 deletions
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index f4cc5719..3dfc0cf5 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,16 @@ +### 2022a rev. 2 + +TZDB 2022b introduces `Europe/Kyiv` and merges more time zones which were +alike since 1970. These changes require ICU patches. + +Though the reason why 2022b was released are changes in Chile. As they have +to be delivered by the 3rd of September and ICU patches are not ready, +decision was made to prepare smaller release which does not need ICU patches. + +tzdata archieve is prepared manually by applying Iran and Chile changes on +top of 2022a tag. + + ### 2022a This update includes pre-1970 diff --git a/apex/Android.bp b/apex/Android.bp index 7b0cea35..64154ff4 100644 --- a/apex/Android.bp +++ b/apex/Android.bp @@ -21,7 +21,7 @@ package { apex_defaults { name: "com.android.tzdata-defaults", updatable: true, - min_sdk_version: "31", + min_sdk_version: "33", // Use a custom AndroidManifest.xml used for API targeting. androidManifest: ":com.android.tzdata-androidManifest", diff --git a/apex/tests/AndroidTest.xml b/apex/tests/AndroidTest.xml index 1981a5ba..6e2923d2 100644 --- a/apex/tests/AndroidTest.xml +++ b/apex/tests/AndroidTest.xml @@ -34,5 +34,7 @@ <option name="mainline-module-package-name" value="com.google.android.tzdata2" /> <!-- This module is found on S devices. --> <option name="mainline-module-package-name" value="com.google.android.tzdata3" /> + <!-- This module is found on T devices. --> + <option name="mainline-module-package-name" value="com.google.android.tzdata4" /> </object> </configuration> diff --git a/apex/tests/src/java/android/tzdata/mts/TimeZoneRulesTest.java b/apex/tests/src/java/android/tzdata/mts/TimeZoneRulesTest.java index 96c91d3f..c1050cce 100644 --- a/apex/tests/src/java/android/tzdata/mts/TimeZoneRulesTest.java +++ b/apex/tests/src/java/android/tzdata/mts/TimeZoneRulesTest.java @@ -61,7 +61,10 @@ public class TimeZoneRulesTest { public void getDisplayNameShort_nonHourOffsets() { TimeZone iranTz = TimeZone.getTimeZone("Asia/Tehran"); assertEquals("GMT+03:30", iranTz.getDisplayName(false, TimeZone.SHORT, Locale.UK)); - assertEquals("GMT+04:30", iranTz.getDisplayName(true, TimeZone.SHORT, Locale.UK)); + + TimeZone chathamTz = TimeZone.getTimeZone("Pacific/Chatham"); + assertEquals("GMT+12:45", chathamTz.getDisplayName(false, TimeZone.SHORT, Locale.UK)); + assertEquals("GMT+13:45", chathamTz.getDisplayName(true, TimeZone.SHORT, Locale.UK)); } @Test diff --git a/apex/tests/src/java/android/tzdata/mts/TimeZoneVersionTest.java b/apex/tests/src/java/android/tzdata/mts/TimeZoneVersionTest.java index 7aa27a14..393b2a7b 100644 --- a/apex/tests/src/java/android/tzdata/mts/TimeZoneVersionTest.java +++ b/apex/tests/src/java/android/tzdata/mts/TimeZoneVersionTest.java @@ -51,14 +51,16 @@ public class TimeZoneVersionTest { } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.S) { assertEquals("005", majorVersion); } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.S_V2) { - // TODO Hack for master, which will have the same API level as S_V2 until the next + // S_V2 is 5.x, as the format version did not change from S. + assertEquals("005", majorVersion); + } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.TIRAMISU) { + // TODO Hack for master, which will have the same API level as T until the next // release API is finalized. - if (VersionInfo.ICU_VERSION.getMajor() > 68) { - // T is expected to be 6.x. - assertEquals("006", majorVersion); + if (VersionInfo.ICU_VERSION.getMajor() > 70) { + // U is expected to be 7.x. + assertEquals("007", majorVersion); } else { - // S_V2 is 5.x, as the format version did not change from S. - assertEquals("005", majorVersion); + assertEquals("006", majorVersion); } } else { // If this fails, a new API level has likely been finalized and can be made diff --git a/input_data/android/countryzones.txt b/input_data/android/countryzones.txt index c7fd0cad..dc775819 100644 --- a/input_data/android/countryzones.txt +++ b/input_data/android/countryzones.txt @@ -25,7 +25,7 @@ # a time zone for an Android device. # ianaVersion: The version of the IANA rules this file matches. -ianaVersion:"2022a" +ianaVersion:"2022g" # countries: # @@ -698,16 +698,11 @@ countries:< > timeZoneMappings:< utcOffset:"-3:00" - id:"America/Santarem" - # City: 294K, State:7.79M (Same state as Belem) - priority:7789 - > - timeZoneMappings:< - utcOffset:"-3:00" id:"America/Recife" # City: 1.63M, State: 8.93M priority:8930 > + timeZoneMappings:< utcOffset:"-3:00" id:"America/Fortaleza" @@ -722,6 +717,12 @@ countries:< > timeZoneMappings:< utcOffset:"-3:00" + id:"America/Santarem" + # City: 294K, State:7.79M (Same state as Belem) + priority:7789 + > + timeZoneMappings:< + utcOffset:"-3:00" id:"America/Maceio" # City: 1.02M, State:3.17M priority:3170 @@ -847,6 +848,8 @@ countries:< # 5.43M priority:5430 alternativeIds: "America/Montreal" + alternativeIds: "America/Nipigon" + alternativeIds: "America/Thunder_Bay" alternativeIds: "Canada/Eastern" > timeZoneMappings:< @@ -868,6 +871,7 @@ countries:< id:"America/Winnipeg" # 712K priority:712 + alternativeIds: "America/Rainy_River" alternativeIds: "Canada/Central" > timeZoneMappings:< @@ -911,33 +915,15 @@ countries:< # 1.12K priority:1 > - - timeZoneMappings:< - utcOffset:"-5:00" - id:"America/Thunder_Bay" - # 108K - priority:108 - > timeZoneMappings:< utcOffset:"-5:00" id:"America/Iqaluit" + alternativeIds:"America/Pangnirtung" # 7.74K priority:8 > timeZoneMappings:< utcOffset:"-5:00" - id:"America/Nipigon" - # 1.63K - priority:1 - > - timeZoneMappings:< - utcOffset:"-5:00" - id:"America/Pangnirtung" - # 1.48K - priority:1 - > - timeZoneMappings:< - utcOffset:"-5:00" id:"America/Atikokan" # 2.75K priority:3 @@ -965,12 +951,6 @@ countries:< > timeZoneMappings:< utcOffset:"-6:00" - id:"America/Rainy_River" - # 0.84K - priority:1 - > - timeZoneMappings:< - utcOffset:"-6:00" id:"America/Resolute" # 0.20K priority:1 @@ -1014,17 +994,17 @@ countries:< > timeZoneMappings:< utcOffset:"-7:00" - id:"America/Dawson" - # 1.38K - priority:1 - > - timeZoneMappings:< - utcOffset:"-7:00" id:"America/Whitehorse" # 25.1K priority:251 alternativeIds: "Canada/Yukon" > + timeZoneMappings:< + utcOffset:"-7:00" + id:"America/Dawson" + # 1.38K + priority:1 + > > # COCOS (KEELING) ISLANDS @@ -1214,6 +1194,7 @@ countries:< timeZoneMappings:< utcOffset:"2:00" id:"Asia/Nicosia" + alternativeIds:"Europe/Nicosia" > timeZoneMappings:< utcOffset:"2:00" @@ -1546,7 +1527,7 @@ countries:< > timeZoneMappings:< - utcOffset:"-3:00" + utcOffset:"-2:00" id:"America/Nuuk" alternativeIds: "America/Godthab" > @@ -1836,7 +1817,7 @@ countries:< countries:< isoCode:"jo" timeZoneMappings:< - utcOffset:"2:00" + utcOffset:"3:00" id:"Asia/Amman" > > @@ -1889,10 +1870,8 @@ countries:< timeZoneMappings:< utcOffset:"13:00" - # TODO(b/204539416) Switch to Pacific/Kanton when CLDR has exemplar - # location translations. - id:"Pacific/Enderbury" - alternativeIds: "Pacific/Kanton" + id:"Pacific/Kanton" + alternativeIds:"Pacific/Enderbury" > timeZoneMappings:< @@ -2216,17 +2195,17 @@ countries:< defaultTimeZoneId:"Asia/Ulaanbaatar" timeZoneMappings:< utcOffset:"8:00" - id:"Asia/Choibalsan" - # 38K - priority:38 - > - timeZoneMappings:< - utcOffset:"8:00" id:"Asia/Ulaanbaatar" # 1.145M priority:1145 alternativeIds: "Asia/Ulan_Bator" > + timeZoneMappings:< + utcOffset:"8:00" + id:"Asia/Choibalsan" + # 38K + priority:38 + > timeZoneMappings:< utcOffset:"7:00" @@ -2347,6 +2326,12 @@ countries:< > timeZoneMappings:< utcOffset:"-6:00" + id:"America/Chihuahua" + # 878K + priority:878 + > + timeZoneMappings:< + utcOffset:"-6:00" id:"America/Bahia_Banderas" # 83.7K priority:84 @@ -2357,6 +2342,12 @@ countries:< # 520K priority:520 > + timeZoneMappings:< + utcOffset:"-6:00" + id:"America/Ojinaga" + # 28.0K + priority:28 + > timeZoneMappings:< utcOffset:"-5:00" @@ -2367,17 +2358,11 @@ countries:< timeZoneMappings:< utcOffset:"-7:00" - id:"America/Chihuahua" - # 878K - priority:878 - > - timeZoneMappings:< - utcOffset:"-7:00" - id:"America/Mazatlan" - # 658K - priority:658 - alternativeIds: "Mexico/BajaSur" + id:"America/Ciudad_Juarez" + # 2.5M + priority:2539 > + timeZoneMappings:< utcOffset:"-7:00" id:"America/Hermosillo" @@ -2386,9 +2371,10 @@ countries:< > timeZoneMappings:< utcOffset:"-7:00" - id:"America/Ojinaga" - # 28.0K - priority:28 + id:"America/Mazatlan" + # 658K + priority:658 + alternativeIds: "Mexico/BajaSur" > timeZoneMappings:< @@ -3138,7 +3124,7 @@ countries:< countries:< isoCode:"sy" timeZoneMappings:< - utcOffset:"2:00" + utcOffset:"3:00" id:"Asia/Damascus" > > @@ -3258,6 +3244,7 @@ countries:< timeZoneMappings:< utcOffset:"3:00" id:"Europe/Istanbul" + alternativeIds: "Asia/Istanbul" alternativeIds: "Turkey" > > @@ -3301,33 +3288,26 @@ countries:< > # UKRAINE -# -# Priorities assigned on 20180309 using: -# https://en.wikipedia.org/wiki/List_of_cities_in_Ukraine -# Priorities are just an abstract score. countries:< isoCode:"ua" defaultTimeZoneId:"Europe/Kiev" timeZoneMappings:< utcOffset:"2:00" id:"Europe/Kiev" - priority:3 - > - timeZoneMappings:< - utcOffset:"2:00" - id:"Europe/Zaporozhye" - priority:2 - > - timeZoneMappings:< - utcOffset:"2:00" - id:"Europe/Uzhgorod" - priority:1 + # Europe/Kyiv was added in TZDB 2022b (August 2022) as a replacement ID + # for the zone previously known as Europe/Kiev. Europe/Kiev is retained + # as an alias. + # Also, there is no translation of Europe/Kyiv available + # in ICU. + # TODO(b/250606303): Swap Europe/Kyiv and Europe/Kiev in Android V. + # By then we expect most systems will know about the new ID. + alternativeIds:"Europe/Kyiv" + alternativeIds:"Europe/Zaporozhye" + alternativeIds:"Europe/Uzhgorod" > timeZoneMappings:< utcOffset:"3:00" id:"Europe/Simferopol" - # ? - priority:1 # http://b/73922616 shownInPicker:false > diff --git a/input_data/iana/tzdata2022a.tar.gz b/input_data/iana/tzdata2022a.tar.gz Binary files differdeleted file mode 100644 index 87a5aeac..00000000 --- a/input_data/iana/tzdata2022a.tar.gz +++ /dev/null diff --git a/input_data/iana/tzdata2022g.tar.gz b/input_data/iana/tzdata2022g.tar.gz Binary files differnew file mode 100644 index 00000000..a9be4251 --- /dev/null +++ b/input_data/iana/tzdata2022g.tar.gz diff --git a/input_data/iana/tzdata2022g.tar.gz.asc b/input_data/iana/tzdata2022g.tar.gz.asc new file mode 100644 index 00000000..d972058d --- /dev/null +++ b/input_data/iana/tzdata2022g.tar.gz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEfjeSqdis99YzvBWI7ZfpDmKqfjQFAmOGOvAACgkQ7ZfpDmKq +fjSedhAAu8XkzqB8NmXDYfEurBCUPe7zCBxBe7yqdt5W+tDA9snOtab3d8Oq7Lsb +vNZfh4qHIxNbEYpoXOc0Qce3XKXGgyKDmZeFYQJ0ziqoZXetNLQEmg7T/H2m3GHl +eo7K3w2hvyBB26FuDtimE5pzuJo9qJLXDp2SbOAbKa1w5HibyvZBOfcQozZ4CBmE +mBc8LzyFY3zOhiy7CGYskqOzatNa0Eid95RkK2RXXTnN965N1qdyOz3z9SkJFH9h +MR84VGYBmk0UGdPGmp1imkGmIrO/8AFny19ECCe4F74o2DFSPzANOaEh+i3fIP3d +GNR96la9GGopmna+VNQt6zxdw4DHRoNkAupnJ2NVM0lbAMOG0mmwCFkCzW4gzTVm +7NdAtZyH+HjiKYPdQNIHbsvl0K1qIo1yXrb4jTd8eXaxA65msCOOwjqWk7a8ZjrJ +NrLNmGeLow9svofEAeLpc9BUgwF90JGIlb+tPYovyj/xSU9vhQl1ZEmFYYdaN781 +rGZ5jKtwBZWoAxW1Copf8S3jcxleSVMFo6MTEU+K+svZLd8SH5BnETa0fYWSTzKA +uh2Y4V6pFe0/JVVC15mYkytbP6TC6prRmi44jRHtVRDtizGd7FFxYacIApkhBVi2 +Qb8Qy+oZySwL+dbRlu+bA9nHIdACtxRouVEWpAecCBLaK3kBb7I= +=6g+2 +-----END PGP SIGNATURE----- diff --git a/input_tools/android/common/src/testing/java/com/android/libcore/timezone/testing/TestUtils.java b/input_tools/android/common/src/testing/java/com/android/libcore/timezone/testing/TestUtils.java index 55bb2150..3cd5861d 100644 --- a/input_tools/android/common/src/testing/java/com/android/libcore/timezone/testing/TestUtils.java +++ b/input_tools/android/common/src/testing/java/com/android/libcore/timezone/testing/TestUtils.java @@ -16,7 +16,9 @@ package com.android.libcore.timezone.testing; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; @@ -75,4 +77,15 @@ public final class TestUtils { assertTrue(s + " must contain " + expected, s.contains(expected)); } } + + public static byte[] readFully(InputStream is) throws IOException { + int read; + byte[] buffer = new byte[1024]; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + while ((read = is.read(buffer)) != -1) { + baos.write(buffer, 0, read); + } + + return baos.toByteArray(); + } } diff --git a/input_tools/android/tzids/src/main/java/com/android/timezone/tzids/TimeZoneIds.java b/input_tools/android/tzids/src/main/java/com/android/timezone/tzids/TimeZoneIds.java index eedacbc1..20667000 100644 --- a/input_tools/android/tzids/src/main/java/com/android/timezone/tzids/TimeZoneIds.java +++ b/input_tools/android/tzids/src/main/java/com/android/timezone/tzids/TimeZoneIds.java @@ -203,7 +203,7 @@ public class TimeZoneIds { Map<String, TzIdsProto.TimeZoneReplacement> replacementLookupMap, Instant replacementThreshold) { TzIdsProto.TimeZoneReplacement current = start; - while(current.getFromMillis() <= replacementThreshold.toEpochMilli()) { + while (current.getFromMillis() <= replacementThreshold.toEpochMilli()) { TzIdsProto.TimeZoneReplacement next = replacementLookupMap.get(current.getReplacementId()); if (next == null) { diff --git a/input_tools/android/tzlookup_generator/src/main/java/com/android/libcore/timezone/tzlookup/TzLookupFile.java b/input_tools/android/tzlookup_generator/src/main/java/com/android/libcore/timezone/tzlookup/TzLookupFile.java index 446b8576..6a568c85 100644 --- a/input_tools/android/tzlookup_generator/src/main/java/com/android/libcore/timezone/tzlookup/TzLookupFile.java +++ b/input_tools/android/tzlookup_generator/src/main/java/com/android/libcore/timezone/tzlookup/TzLookupFile.java @@ -25,8 +25,10 @@ import java.io.Writer; import java.nio.charset.StandardCharsets; import java.time.Instant; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Objects; +import java.util.Set; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; @@ -172,6 +174,7 @@ final class TzLookupFile { private final boolean defaultTimeZoneBoost; private final boolean everUsesUtc; private final List<TimeZoneMapping> timeZoneMappings = new ArrayList<>(); + private final Set<String> alreadyDefinedTimeZoneIds = new HashSet<>(); Country(String isoCode, String defaultTimeZoneId, boolean defaultTimeZoneBoost, boolean everUsesUtc) { @@ -182,6 +185,25 @@ final class TzLookupFile { } void addTimeZoneMapping(TimeZoneMapping timeZoneMapping) { + String notUsedReplacementId = timeZoneMapping.notAfterReplacementId; + + // It makes sense to have the highest-priority zones first for time zone detection, + // which uses the first valid time zone that matches local offset information. + // "Replaced by" is a strong signal that one zone is subordinate to another. + // Therefore, zones should usually come after the zones that replaced them. + if (notUsedReplacementId != null + && !alreadyDefinedTimeZoneIds.contains(notUsedReplacementId)) { + String errorMessage = ("Wrong mapping order for %s: %s is replaced by %s," + + " but comes before it.") + .formatted( + isoCode, + timeZoneMapping.olsonId, + notUsedReplacementId); + throw new IllegalArgumentException(errorMessage); + } + + alreadyDefinedTimeZoneIds.add(timeZoneMapping.olsonId); + alreadyDefinedTimeZoneIds.addAll(timeZoneMapping.alternativeZoneIds); timeZoneMappings.add(timeZoneMapping); } diff --git a/input_tools/android/tzlookup_generator/src/main/java/com/android/libcore/timezone/tzlookup/Tzdb.java b/input_tools/android/tzlookup_generator/src/main/java/com/android/libcore/timezone/tzlookup/Tzdb.java index 855c94f2..ef780285 100644 --- a/input_tools/android/tzlookup_generator/src/main/java/com/android/libcore/timezone/tzlookup/Tzdb.java +++ b/input_tools/android/tzlookup_generator/src/main/java/com/android/libcore/timezone/tzlookup/Tzdb.java @@ -44,9 +44,9 @@ public final class Tzdb { "GMT-0", "GMT0", "HST", "IET", "IST", "JST", "MET", "MIT", "MST", "NET", "NST", "PLT", "PNT", "PRT", "PST", "SST", "UCT", "UTC", "VST", "WET"); - // TODO(b/208768262) These should be added to countryzones.txt. - private static final Set<String> MISSING_TZ_IDS = Set.of("US/Pacific-New", "Asia/Istanbul", - "Europe/Nicosia", "Greenwich"); + // US/Pacific-New was deleted from IANA TZDB, but exists in ICU, so it can't be removed yet. + // Greenwich is just an alias to Etc/GMT, and none of them should appear in the tzlookup file. + private static final Set<String> MISSING_TZ_IDS = Set.of("US/Pacific-New", "Greenwich"); // According to backward file comment this name exceeds 14 chars limit and is unused misnomer. // Supported by ICU only, not valid TZDB time zone IDs. Not added to tzlookup.xml. diff --git a/input_tools/android/tzlookup_generator/src/main/java/com/android/libcore/timezone/tzlookup/zonetree/CountryZoneTree.java b/input_tools/android/tzlookup_generator/src/main/java/com/android/libcore/timezone/tzlookup/zonetree/CountryZoneTree.java index 43ace042..a3bf3485 100644 --- a/input_tools/android/tzlookup_generator/src/main/java/com/android/libcore/timezone/tzlookup/zonetree/CountryZoneTree.java +++ b/input_tools/android/tzlookup_generator/src/main/java/com/android/libcore/timezone/tzlookup/zonetree/CountryZoneTree.java @@ -511,16 +511,31 @@ public final class CountryZoneTree { } Instant endInstant = node.getEndInstant(); - String replacementTimeZoneId = getReplacementTimeZoneIdOrNull(node); if (!node.isLeaf()) { ZoneInfo primaryZone = node.getPrimaryZoneInfo(); - addZoneEntryIfMissing(endInstant, replacementTimeZoneId, primaryZone); + String replacementId = getReplacementTimeZoneIdOrNull(node); + addZoneEntryIfMissing(endInstant, replacementId, primaryZone); } else { - // In some rare cases (e.g. Canada: Swift_Current and Creston) zones have agreed + // In some rare cases (e.g. Canada: Yellowknife and Edmonton) zones have agreed // completely since 1970 so some leaves may have multiple zones. So, attempt to // add all zones for leaves, not just the primary. for (ZoneInfo zoneInfo : node.getZoneInfos()) { - addZoneEntryIfMissing(endInstant, replacementTimeZoneId, zoneInfo); + Instant notAfterInstant; + String replacementId; + if (zoneInfo.equals(node.primaryZoneInfo)) { + // Handle the primaryZoneInfo in the normal way. + replacementId = getReplacementTimeZoneIdOrNull(node); + notAfterInstant = endInstant; + } else { + // For zoneInfos that are not the primary for the node, we nominate the + // primary zone of this node as the replacement, and since the zoneInfo + // is already replaced by the time this node starts, we can use + // startInstant as the notAfterInstant value, i.e. it was replaced at + // the earliest time we know about. + notAfterInstant = node.getStartInstant(); + replacementId = node.primaryZoneInfo.getZoneId(); + } + addZoneEntryIfMissing(notAfterInstant, replacementId, zoneInfo); } } } @@ -530,11 +545,6 @@ public final class CountryZoneTree { * this method returns that zone ID. {@code null} is returned otherwise. */ private String getReplacementTimeZoneIdOrNull(ZoneNode node) { - if (node.isRoot()) { - // There is no parent node, so there can be no replacement ID. - return null; - } - String zoneId = node.primaryZoneInfo.getZoneId(); String replacementId = node.getParent().primaryZoneInfo.getZoneId(); if (Objects.equals(zoneId, replacementId)) { @@ -547,20 +557,20 @@ public final class CountryZoneTree { } private void addZoneEntryIfMissing( - Instant endInstant, String replacementTimeZoneId, ZoneInfo zoneInfo) { + Instant notAfterInstant, String replacementTimeZoneId, ZoneInfo zoneInfo) { String zoneId = zoneInfo.getZoneId(); if (Objects.equals(zoneId, replacementTimeZoneId)) { throw new IllegalStateException(zoneId + " cannot replace itself. Cycle!"); } - if (!notAfterCutOff.isAfter(endInstant)) { - // notAfterCutOff <= endInstant - endInstant = null; + if (!notAfterCutOff.isAfter(notAfterInstant)) { + // notAfterCutOff <= notAfterInstant + notAfterInstant = null; replacementTimeZoneId = null; } if (!zoneUsage.hasEntry(zoneId)) { - zoneUsage.addEntry(zoneId, endInstant, replacementTimeZoneId); + zoneUsage.addEntry(zoneId, notAfterInstant, replacementTimeZoneId); } } diff --git a/input_tools/android/tzlookup_generator/src/test/java/com/android/libcore/timezone/tzlookup/TzLookupGeneratorTest.java b/input_tools/android/tzlookup_generator/src/test/java/com/android/libcore/timezone/tzlookup/TzLookupGeneratorTest.java index c1ef06be..1806cfd4 100644 --- a/input_tools/android/tzlookup_generator/src/test/java/com/android/libcore/timezone/tzlookup/TzLookupGeneratorTest.java +++ b/input_tools/android/tzlookup_generator/src/test/java/com/android/libcore/timezone/tzlookup/TzLookupGeneratorTest.java @@ -334,7 +334,7 @@ public class TzLookupGeneratorTest { public void incorrectOffset() throws Exception { CountryZonesFile.Country validGbCountry = createValidCountryGb(); CountryZonesFile.Country.Builder gbWithWrongOffsetBuilder = validGbCountry.toBuilder(); - gbWithWrongOffsetBuilder.getTimeZoneMappingsBuilder(0).setUtcOffset("20:00").build(); + gbWithWrongOffsetBuilder.getTimeZoneMappingsBuilder(0).setUtcOffset("20:00"); CountryZonesFile.Country gbWithWrongOffset = gbWithWrongOffsetBuilder.build(); CountryZonesFile.CountryZones countryZones = createValidCountryZones(gbWithWrongOffset); @@ -399,7 +399,7 @@ public class TzLookupGeneratorTest { + ">\n" + "\n" + "timeZoneMappings:<\n" - + " utcOffset:\"-3:00\"\n" + + " utcOffset:\"-2:00\"\n" + " id:\"America/Godthab\"\n" + " alternativeIds: \"America/Nuuk\"\n" + ">\n" @@ -570,11 +570,11 @@ public class TzLookupGeneratorTest { + "<id notafter=\"247042800000\" repl=\"America/Indiana/Vincennes\">America/Indiana/Petersburg</id>\n" + "<id notafter=\"89186400000\" repl=\"America/Indiana/Indianapolis\">America/Indiana/Vevay</id>\n" + "<id>America/Chicago</id>\n" + + "<id notafter=\"1143964800000\" repl=\"America/Chicago\">America/Indiana/Tell_City</id>\n" + "<id notafter=\"688546800000\" repl=\"America/Indiana/Tell_City\">America/Indiana/Knox</id>\n" + "<id notafter=\"104918400000\" repl=\"America/Chicago\">America/Menominee</id>\n" + "<id notafter=\"720000000000\" repl=\"America/Chicago\">America/North_Dakota/Center</id>\n" + "<id notafter=\"1067155200000\" repl=\"America/Chicago\">America/North_Dakota/New_Salem</id>\n" - + "<id notafter=\"1143964800000\" repl=\"America/Chicago\">America/Indiana/Tell_City</id>\n" + "<id notafter=\"1289116800000\" repl=\"America/Chicago\">America/North_Dakota/Beulah</id>\n" + "<id>America/Denver</id>\n" + "<id notafter=\"129114000000\" repl=\"America/Denver\">America/Boise</id>\n" @@ -617,11 +617,11 @@ public class TzLookupGeneratorTest { addReplacement(b, 183535200000L, "America/Indiana/Indianapolis", "America/Indiana/Marengo"); addReplacement(b, 247042800000L, "America/Indiana/Vincennes", "America/Indiana/Petersburg"); addReplacement(b, 89186400000L, "America/Indiana/Indianapolis", "America/Indiana/Vevay"); + addReplacement(b, 1143964800000L, "America/Chicago", "America/Indiana/Tell_City"); addReplacement(b, 688546800000L, "America/Indiana/Tell_City", "America/Indiana/Knox"); addReplacement(b, 104918400000L, "America/Chicago", "America/Menominee"); addReplacement(b, 720000000000L, "America/Chicago", "America/North_Dakota/Center"); addReplacement(b, 1067155200000L, "America/Chicago", "America/North_Dakota/New_Salem"); - addReplacement(b, 1143964800000L, "America/Chicago", "America/Indiana/Tell_City"); addReplacement(b, 1289116800000L, "America/Chicago", "America/North_Dakota/Beulah"); addReplacement(b, 129114000000L, "America/Denver", "America/Boise"); addReplacement(b, 436359600000L, "America/Anchorage", "America/Juneau"); @@ -857,6 +857,40 @@ public class TzLookupGeneratorTest { } @Test + public void shouldFail_whenAnAliasComesBeforeOriginalTimeZone() throws Exception { + // These time zones relationship is unlikely to change judging by the recent + // TZDB updates. + CountryZonesFile.Country country = + CountryZonesFile.Country.newBuilder() + .setIsoCode("de") + .setDefaultTimeZoneId("Europe/Berlin") + .addTimeZoneMappings( + CountryZonesFile.TimeZoneMapping.newBuilder() + .setUtcOffset("01:00") + .setId("Europe/Busingen")) + .addTimeZoneMappings( + CountryZonesFile.TimeZoneMapping.newBuilder() + .setUtcOffset("01:00") + .setId("Europe/Berlin")) + .build(); + + CountryZonesFile.CountryZones countryZones = createValidCountryZones(country); + String countryZonesFile = createCountryZonesFile(countryZones); + + String zoneTabFile = createZoneTabFile( + List.of( + new ZoneTabFile.CountryEntry("DE", "Europe/Berlin"), + new ZoneTabFile.CountryEntry("DE", "Europe/Busingen"))); + String tzlookupFile = createTempFileName("tzlookup"); + String tzIdsFile = createTempFileName("tzids"); + + TzLookupGenerator tzLookupGenerator = new TzLookupGenerator( + countryZonesFile, zoneTabFile, tzlookupFile, tzIdsFile); + + assertFalse(tzLookupGenerator.execute(false /* validateAllIanaIdsAreMapped */)); + } + + @Test public void shouldFail_whenCountryzonesMissesTimeZone() throws Exception { CountryZonesFile.Country gbCountry = CountryZonesFile.Country.newBuilder() @@ -1039,6 +1073,11 @@ public class TzLookupGeneratorTest { + " >\n" + " timeZoneMappings:<\n" + " utcOffset:\"-6:00\"\n" + + " id:\"America/Indiana/Tell_City\"\n" + + " priority:9\n" + + " >\n" + + " timeZoneMappings:<\n" + + " utcOffset:\"-6:00\"\n" + " id:\"America/Indiana/Knox\"\n" + " >\n" + " timeZoneMappings:<\n" @@ -1055,11 +1094,6 @@ public class TzLookupGeneratorTest { + " >\n" + " timeZoneMappings:<\n" + " utcOffset:\"-6:00\"\n" - + " id:\"America/Indiana/Tell_City\"\n" - + " priority:9\n" - + " >\n" - + " timeZoneMappings:<\n" - + " utcOffset:\"-6:00\"\n" + " id:\"America/North_Dakota/Beulah\"\n" + " >\n" + " timeZoneMappings:<\n" diff --git a/input_tools/android/zone_compactor/Android.bp b/input_tools/android/zone_compactor/Android.bp index b116ca20..e325ca3c 100644 --- a/input_tools/android/zone_compactor/Android.bp +++ b/input_tools/android/zone_compactor/Android.bp @@ -24,3 +24,16 @@ java_binary_host { main_class: "ZoneCompactor", srcs: ["main/java/**/*.java"], } + +java_test_host { + name: "zone_compactor_tests", + srcs: ["test/java/**/*.java"], + test_options: { + unit_test: true, + }, + static_libs: [ + "zone_compactor", + "junit", + "tztools_common_testing", + ], +} diff --git a/input_tools/android/zone_compactor/main/java/ZoneCompactor.java b/input_tools/android/zone_compactor/main/java/ZoneCompactor.java index a10528ac..72c0cac4 100644 --- a/input_tools/android/zone_compactor/main/java/ZoneCompactor.java +++ b/input_tools/android/zone_compactor/main/java/ZoneCompactor.java @@ -68,33 +68,41 @@ public class ZoneCompactor { public ZoneCompactor(String setupFile, String dataDirectory, String outputDirectory, String version) throws Exception { // Read the setup file and concatenate all the data. + Set<String> zoneIds = new LinkedHashSet<>(); + try (BufferedReader reader = new BufferedReader(new FileReader(setupFile))) { + String s; + while ((s = reader.readLine()) != null) { + s = s.trim(); + StringTokenizer st = new StringTokenizer(s); + String lineType = st.nextToken(); + if (lineType.startsWith("Link")) { + String to = st.nextToken(); + String from = st.nextToken(); + links.put(from, to); + } else if (lineType.startsWith("Zone")) { + String zoneId = st.nextToken(); + if (!zoneIds.add(zoneId)) { + throw new IllegalStateException(String.format("There are at least two Zone entries " + + "for %s in the setup file", zoneId)); + } + } + } + } + ByteArrayOutputStream allData = new ByteArrayOutputStream(); - BufferedReader reader = new BufferedReader(new FileReader(setupFile)); - String s; + int offset = 0; - while ((s = reader.readLine()) != null) { - s = s.trim(); - StringTokenizer st = new StringTokenizer(s); - String lineType = st.nextToken(); - if (lineType.startsWith("Link")) { - String to = st.nextToken(); - String from = st.nextToken(); - links.put(from, to); - } else if (lineType.startsWith("Zone")) { - String zoneId = st.nextToken(); - String link = links.get(zoneId); - if (link == null) { - File sourceFile = new File(dataDirectory, zoneId); - long length = sourceFile.length(); - offsets.put(zoneId, offset); - lengths.put(zoneId, (int) length); - - offset += length; - copyFile(sourceFile, allData); - } + for (String zoneId : zoneIds) { + if (!links.containsKey(zoneId)) { + File sourceFile = new File(dataDirectory, zoneId); + long length = sourceFile.length(); + offsets.put(zoneId, offset); + lengths.put(zoneId, (int) length); + + offset += length; + copyFile(sourceFile, allData); } } - reader.close(); // Fill in fields for links. for (String from : links.keySet()) { diff --git a/input_tools/android/zone_compactor/test/java/ZoneCompactorTest.java b/input_tools/android/zone_compactor/test/java/ZoneCompactorTest.java new file mode 100644 index 00000000..fd0a775f --- /dev/null +++ b/input_tools/android/zone_compactor/test/java/ZoneCompactorTest.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.android.libcore.timezone.testing.TestUtils; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.FileInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +import static java.nio.charset.StandardCharsets.US_ASCII; + +public final class ZoneCompactorTest { + + private static final String TZDB_VERSION = "tzdata2030a"; + private static final byte[] ARBITRARY_TZIF_CONTENT = "TZif3contentgoeshere".getBytes(US_ASCII); + + private Path inputFilesDir; + private Path outputFilesDir; + + @Before + public void setup() throws Exception { + inputFilesDir = Files.createTempDirectory("tzdata"); + outputFilesDir = Files.createTempDirectory("output"); + } + + @Test + public void shouldFollowLinkChains_definedInForwardOrder() throws Exception { + String zoneAndLinks = + "Link America/Toronto America/Rainy_Inlet\n" + + "Link America/Rainy_Inlet America/Nipigon\n" + + "Zone America/Toronto"; + + String setupFile = TestUtils.createFile(inputFilesDir, zoneAndLinks); + Files.createDirectories(inputFilesDir.resolve("America")); + Path americaToronto = Files.createFile(inputFilesDir.resolve("America").resolve("Toronto")); + + Files.write(americaToronto, ARBITRARY_TZIF_CONTENT); + + new ZoneCompactor( + setupFile, + inputFilesDir.toString(), + outputFilesDir.toString(), + TZDB_VERSION); + + Path resultTzdata = outputFilesDir.resolve("tzdata"); + assertTrue(Files.exists(resultTzdata)); + + try (FileInputStream fis = new FileInputStream(resultTzdata.toFile())) { + byte[] allData = TestUtils.readFully(fis); + + assertEquals(tzdataLength(3, List.of(ARBITRARY_TZIF_CONTENT)), allData.length); + } + } + + @Test + public void shouldFollowLinkChains_definedInBackwardsOrder() throws Exception { + String zoneAndLinks = + "Link America/Rainy_Inlet America/Nipigon\n" + + "Link America/Toronto America/Rainy_Inlet\n" + + "Zone America/Toronto"; + + String setupFile = TestUtils.createFile(inputFilesDir, zoneAndLinks); + Files.createDirectories(inputFilesDir.resolve("America")); + Path americaToronto = Files.createFile(inputFilesDir.resolve("America").resolve("Toronto")); + + Files.write(americaToronto, ARBITRARY_TZIF_CONTENT); + + new ZoneCompactor( + setupFile, + inputFilesDir.toString(), + outputFilesDir.toString(), + TZDB_VERSION); + + Path resultTzdata = outputFilesDir.resolve("tzdata"); + assertTrue(Files.exists(resultTzdata)); + + try (FileInputStream fis = new FileInputStream(resultTzdata.toFile())) { + byte[] allData = TestUtils.readFully(fis); + + assertEquals(tzdataLength(3, List.of(ARBITRARY_TZIF_CONTENT)), allData.length); + } + } + + @Test + public void shouldFail_ifSetupFileHasMultipleZoneEntriesOfTheSameTimeZoneId() throws Exception { + String zoneAndLinks = + "Zone America/Toronto\n" + + "Zone America/Toronto"; + + String setupFile = TestUtils.createFile(inputFilesDir, zoneAndLinks); + Files.createDirectories(inputFilesDir.resolve("America")); + Path americaToronto = Files.createFile(inputFilesDir.resolve("America").resolve("Toronto")); + + Files.write(americaToronto, ARBITRARY_TZIF_CONTENT); + + assertThrows( + IllegalStateException.class, + () -> new ZoneCompactor( + setupFile, + inputFilesDir.toString(), + outputFilesDir.toString(), + TZDB_VERSION)); + } + + private static int tzdataLength(int timeZonesCount, List<byte[]> tzifContents) { + int allDataLength = tzifContents.stream().mapToInt(array -> array.length).sum(); + + // 12 bytes is version - tzdataYYYYa\0 + // 4 * 3 - version is followed by 3 ints: index, data, and final offsets. + // 40 + 4 * 3 - 40 is for time zone name, followed by offset, length, and unused int. + // The rest is all data concatenated as-it-is. + return 12 + 3 * 4 + (40 + 4 * 3) * timeZonesCount + allDataLength; + } +} diff --git a/output_data/android/tzids.prototxt b/output_data/android/tzids.prototxt index 9809ebec..1a01ed01 100644 --- a/output_data/android/tzids.prototxt +++ b/output_data/android/tzids.prototxt @@ -1,5 +1,5 @@ # Autogenerated file - DO NOT EDIT. -ianaVersion: "2022a" +ianaVersion: "2022g" countryMappings { isoCode: "ad" timeZoneIds: "Europe/Andorra" @@ -335,11 +335,6 @@ countryMappings { fromMillis: 1550368800000 } timeZoneReplacements { - replacedId: "America/Santarem" - replacementId: "America/Recife" - fromMillis: 1214280000000 - } - timeZoneReplacements { replacedId: "America/Recife" replacementId: "America/Bahia" fromMillis: 1330221600000 @@ -355,6 +350,11 @@ countryMappings { fromMillis: 1013911200000 } timeZoneReplacements { + replacedId: "America/Santarem" + replacementId: "America/Recife" + fromMillis: 1214280000000 + } + timeZoneReplacements { replacedId: "America/Maceio" replacementId: "America/Fortaleza" fromMillis: 824004000000 @@ -432,6 +432,14 @@ countryMappings { preferredId: "America/Toronto" } timeZoneLinks { + alternativeId: "America/Nipigon" + preferredId: "America/Toronto" + } + timeZoneLinks { + alternativeId: "America/Thunder_Bay" + preferredId: "America/Toronto" + } + timeZoneLinks { alternativeId: "Canada/Eastern" preferredId: "America/Toronto" } @@ -444,6 +452,10 @@ countryMappings { preferredId: "America/Edmonton" } timeZoneLinks { + alternativeId: "America/Rainy_River" + preferredId: "America/Winnipeg" + } + timeZoneLinks { alternativeId: "Canada/Central" preferredId: "America/Winnipeg" } @@ -456,6 +468,10 @@ countryMappings { preferredId: "America/St_Johns" } timeZoneLinks { + alternativeId: "America/Pangnirtung" + preferredId: "America/Iqaluit" + } + timeZoneLinks { alternativeId: "America/Coral_Harbour" preferredId: "America/Atikokan" } @@ -483,26 +499,11 @@ countryMappings { fromMillis: 1299996000000 } timeZoneReplacements { - replacedId: "America/Thunder_Bay" - replacementId: "America/Toronto" - fromMillis: 120636000000 - } - timeZoneReplacements { replacedId: "America/Iqaluit" replacementId: "America/Toronto" fromMillis: 972802800000 } timeZoneReplacements { - replacedId: "America/Nipigon" - replacementId: "America/Thunder_Bay" - fromMillis: 89186400000 - } - timeZoneReplacements { - replacedId: "America/Pangnirtung" - replacementId: "America/Iqaluit" - fromMillis: 796806000000 - } - timeZoneReplacements { replacedId: "America/Swift_Current" replacementId: "America/Regina" fromMillis: 73472400000 @@ -513,11 +514,6 @@ countryMappings { fromMillis: 1130659200000 } timeZoneReplacements { - replacedId: "America/Rainy_River" - replacementId: "America/Rankin_Inlet" - fromMillis: 986112000000 - } - timeZoneReplacements { replacedId: "America/Resolute" replacementId: "America/Winnipeg" fromMillis: 1173600000000 @@ -525,7 +521,7 @@ countryMappings { timeZoneReplacements { replacedId: "America/Yellowknife" replacementId: "America/Edmonton" - fromMillis: 309945600000 + fromMillis: 0 } timeZoneReplacements { replacedId: "America/Creston" @@ -539,7 +535,7 @@ countryMappings { } timeZoneReplacements { replacedId: "America/Inuvik" - replacementId: "America/Yellowknife" + replacementId: "America/Edmonton" fromMillis: 294228000000 } timeZoneReplacements { @@ -657,6 +653,10 @@ countryMappings { isoCode: "cy" timeZoneIds: "Asia/Nicosia" timeZoneIds: "Asia/Famagusta" + timeZoneLinks { + alternativeId: "Europe/Nicosia" + preferredId: "Asia/Nicosia" + } } countryMappings { isoCode: "cz" @@ -1009,11 +1009,11 @@ countryMappings { countryMappings { isoCode: "ki" timeZoneIds: "Pacific/Kiritimati" - timeZoneIds: "Pacific/Enderbury" + timeZoneIds: "Pacific/Kanton" timeZoneIds: "Pacific/Tarawa" timeZoneLinks { - alternativeId: "Pacific/Kanton" - preferredId: "Pacific/Enderbury" + alternativeId: "Pacific/Enderbury" + preferredId: "Pacific/Kanton" } } countryMappings { @@ -1242,9 +1242,8 @@ countryMappings { timeZoneIds: "America/Mexico_City" timeZoneIds: "America/Matamoros" timeZoneIds: "America/Cancun" - timeZoneIds: "America/Chihuahua" + timeZoneIds: "America/Ciudad_Juarez" timeZoneIds: "America/Hermosillo" - timeZoneIds: "America/Ojinaga" timeZoneIds: "America/Tijuana" timeZoneLinks { alternativeId: "Mexico/General" @@ -1277,14 +1276,24 @@ countryMappings { fromMillis: 594198000000 } timeZoneReplacements { + replacedId: "America/Chihuahua" + replacementId: "America/Mexico_City" + fromMillis: 1667116800000 + } + timeZoneReplacements { replacedId: "America/Bahia_Banderas" replacementId: "America/Mexico_City" fromMillis: 1270371600000 } timeZoneReplacements { + replacedId: "America/Ojinaga" + replacementId: "America/Matamoros" + fromMillis: 1667718000000 + } + timeZoneReplacements { replacedId: "America/Mazatlan" - replacementId: "America/Chihuahua" - fromMillis: 891766800000 + replacementId: "America/Hermosillo" + fromMillis: 1667116800000 } } countryMappings { @@ -1293,7 +1302,7 @@ countryMappings { timeZoneReplacements { replacedId: "Asia/Kuching" replacementId: "Asia/Kuala_Lumpur" - fromMillis: 378664200000 + fromMillis: 378662400000 } } countryMappings { @@ -1672,6 +1681,10 @@ countryMappings { isoCode: "tr" timeZoneIds: "Europe/Istanbul" timeZoneLinks { + alternativeId: "Asia/Istanbul" + preferredId: "Europe/Istanbul" + } + timeZoneLinks { alternativeId: "Turkey" preferredId: "Europe/Istanbul" } @@ -1704,15 +1717,17 @@ countryMappings { isoCode: "ua" timeZoneIds: "Europe/Kiev" timeZoneIds: "Europe/Simferopol" - timeZoneReplacements { - replacedId: "Europe/Zaporozhye" - replacementId: "Europe/Kiev" - fromMillis: 686102400000 + timeZoneLinks { + alternativeId: "Europe/Kyiv" + preferredId: "Europe/Kiev" } - timeZoneReplacements { - replacedId: "Europe/Uzhgorod" - replacementId: "Europe/Zaporozhye" - fromMillis: 686091600000 + timeZoneLinks { + alternativeId: "Europe/Uzhgorod" + preferredId: "Europe/Kiev" + } + timeZoneLinks { + alternativeId: "Europe/Zaporozhye" + preferredId: "Europe/Kiev" } } countryMappings { diff --git a/output_data/android/tzlookup.xml b/output_data/android/tzlookup.xml index cf236823..d1ee1f7b 100644 --- a/output_data/android/tzlookup.xml +++ b/output_data/android/tzlookup.xml @@ -2,7 +2,7 @@ **** Autogenerated file - DO NOT EDIT **** ---><timezones ianaversion="2022a"> +--><timezones ianaversion="2022g"> <countryzones> <country code="ad" default="Europe/Andorra" everutc="n"> <id>Europe/Andorra</id> @@ -129,10 +129,10 @@ <id alts="Brazil/DeNoronha">America/Noronha</id> <id alts="Brazil/East">America/Sao_Paulo</id> <id notafter="1550368800000" repl="America/Sao_Paulo">America/Bahia</id> - <id notafter="1214280000000" repl="America/Recife">America/Santarem</id> <id notafter="1330221600000" repl="America/Bahia">America/Recife</id> <id notafter="972180000000" repl="America/Recife">America/Fortaleza</id> <id notafter="1013911200000" repl="America/Recife">America/Belem</id> + <id notafter="1214280000000" repl="America/Recife">America/Santarem</id> <id notafter="824004000000" repl="America/Fortaleza">America/Maceio</id> <id notafter="1361066400000" repl="America/Bahia">America/Araguaina</id> <id alts="Brazil/West">America/Manaus</id> @@ -159,34 +159,30 @@ <id>America/Belize</id> </country> <country code="ca" default="America/Toronto" everutc="n"> - <id alts="America/Montreal,Canada/Eastern">America/Toronto</id> + <id alts="America/Montreal,America/Nipigon,America/Thunder_Bay,Canada/Eastern">America/Toronto</id> <id alts="Canada/Pacific">America/Vancouver</id> <id alts="Canada/Mountain">America/Edmonton</id> - <id alts="Canada/Central">America/Winnipeg</id> + <id alts="America/Rainy_River,Canada/Central">America/Winnipeg</id> <id alts="Canada/Atlantic">America/Halifax</id> <id alts="Canada/Newfoundland">America/St_Johns</id> <id notafter="1162098000000" repl="America/Halifax">America/Moncton</id> <id notafter="57733200000" repl="America/Halifax">America/Glace_Bay</id> <id notafter="1299996000000" repl="America/Halifax">America/Goose_Bay</id> <id>America/Blanc-Sablon</id> - <id notafter="120636000000" repl="America/Toronto">America/Thunder_Bay</id> - <id notafter="972802800000" repl="America/Toronto">America/Iqaluit</id> - <id notafter="89186400000" repl="America/Thunder_Bay">America/Nipigon</id> - <id notafter="796806000000" repl="America/Iqaluit">America/Pangnirtung</id> + <id notafter="972802800000" repl="America/Toronto" alts="America/Pangnirtung">America/Iqaluit</id> <id alts="America/Coral_Harbour">America/Atikokan</id> <id alts="Canada/Saskatchewan">America/Regina</id> <id notafter="73472400000" repl="America/Regina">America/Swift_Current</id> <id notafter="1130659200000" repl="America/Winnipeg">America/Rankin_Inlet</id> - <id notafter="986112000000" repl="America/Rankin_Inlet">America/Rainy_River</id> <id notafter="1173600000000" repl="America/Winnipeg">America/Resolute</id> - <id notafter="309945600000" repl="America/Edmonton">America/Yellowknife</id> + <id notafter="0" repl="America/Edmonton">America/Yellowknife</id> <id>America/Dawson_Creek</id> <id notafter="84013200000" repl="America/Dawson_Creek">America/Creston</id> <id notafter="1425808800000" repl="America/Dawson_Creek">America/Fort_Nelson</id> - <id notafter="294228000000" repl="America/Yellowknife">America/Inuvik</id> + <id notafter="294228000000" repl="America/Edmonton">America/Inuvik</id> <id notafter="986115600000" repl="America/Edmonton">America/Cambridge_Bay</id> - <id notafter="120646800000" repl="America/Whitehorse">America/Dawson</id> <id alts="Canada/Yukon">America/Whitehorse</id> + <id notafter="120646800000" repl="America/Whitehorse">America/Dawson</id> </country> <country code="cc" default="Indian/Cocos" everutc="n"> <id>Indian/Cocos</id> @@ -241,7 +237,7 @@ <id>Indian/Christmas</id> </country> <country code="cy" default="Asia/Nicosia" everutc="n"> - <id>Asia/Nicosia</id> + <id alts="Europe/Nicosia">Asia/Nicosia</id> <id>Asia/Famagusta</id> </country> <country code="cz" default="Europe/Prague" everutc="n"> @@ -441,7 +437,7 @@ </country> <country code="ki" default="Pacific/Tarawa" everutc="n"> <id>Pacific/Kiritimati</id> - <id alts="Pacific/Kanton">Pacific/Enderbury</id> + <id alts="Pacific/Enderbury">Pacific/Kanton</id> <id>Pacific/Tarawa</id> </country> <country code="km" default="Indian/Comoro" everutc="n"> @@ -536,8 +532,8 @@ <id alts="Asia/Rangoon">Asia/Yangon</id> </country> <country code="mn" default="Asia/Ulaanbaatar" everutc="n"> - <id notafter="1206889200000" repl="Asia/Ulaanbaatar">Asia/Choibalsan</id> <id alts="Asia/Ulan_Bator">Asia/Ulaanbaatar</id> + <id notafter="1206889200000" repl="Asia/Ulaanbaatar">Asia/Choibalsan</id> <id>Asia/Hovd</id> </country> <country code="mo" default="Asia/Macau" everutc="n"> @@ -571,18 +567,19 @@ <id alts="Mexico/General">America/Mexico_City</id> <id notafter="407653200000" repl="America/Mexico_City">America/Merida</id> <id notafter="594198000000" repl="America/Mexico_City">America/Monterrey</id> + <id notafter="1667116800000" repl="America/Mexico_City">America/Chihuahua</id> <id notafter="1270371600000" repl="America/Mexico_City">America/Bahia_Banderas</id> <id>America/Matamoros</id> + <id notafter="1667718000000" repl="America/Matamoros">America/Ojinaga</id> <id>America/Cancun</id> - <id>America/Chihuahua</id> - <id notafter="891766800000" repl="America/Chihuahua" alts="Mexico/BajaSur">America/Mazatlan</id> + <id>America/Ciudad_Juarez</id> <id>America/Hermosillo</id> - <id>America/Ojinaga</id> + <id notafter="1667116800000" repl="America/Hermosillo" alts="Mexico/BajaSur">America/Mazatlan</id> <id alts="America/Ensenada,America/Santa_Isabel,Mexico/BajaNorte">America/Tijuana</id> </country> <country code="my" default="Asia/Kuala_Lumpur" everutc="n"> <id>Asia/Kuala_Lumpur</id> - <id notafter="378664200000" repl="Asia/Kuala_Lumpur">Asia/Kuching</id> + <id notafter="378662400000" repl="Asia/Kuala_Lumpur">Asia/Kuching</id> </country> <country code="mz" default="Africa/Maputo" everutc="n"> <id>Africa/Maputo</id> @@ -815,7 +812,7 @@ <id>Pacific/Tongatapu</id> </country> <country code="tr" default="Europe/Istanbul" everutc="n"> - <id alts="Turkey">Europe/Istanbul</id> + <id alts="Asia/Istanbul,Turkey">Europe/Istanbul</id> </country> <country code="tt" default="America/Port_of_Spain" everutc="n"> <id alts="America/Virgin">America/Port_of_Spain</id> @@ -830,9 +827,7 @@ <id>Africa/Dar_es_Salaam</id> </country> <country code="ua" default="Europe/Kiev" everutc="n"> - <id>Europe/Kiev</id> - <id notafter="686102400000" repl="Europe/Kiev">Europe/Zaporozhye</id> - <id notafter="686091600000" repl="Europe/Zaporozhye">Europe/Uzhgorod</id> + <id alts="Europe/Kyiv,Europe/Uzhgorod,Europe/Zaporozhye">Europe/Kiev</id> <id picker="n">Europe/Simferopol</id> </country> <country code="ug" default="Africa/Kampala" everutc="n"> diff --git a/output_data/iana/tzdata b/output_data/iana/tzdata Binary files differindex 1c904922..96240c67 100644 --- a/output_data/iana/tzdata +++ b/output_data/iana/tzdata diff --git a/output_data/icu_overlay/icu_tzdata.dat b/output_data/icu_overlay/icu_tzdata.dat Binary files differindex f29b0042..d0782f5d 100644 --- a/output_data/icu_overlay/icu_tzdata.dat +++ b/output_data/icu_overlay/icu_tzdata.dat diff --git a/output_data/version/tz_version b/output_data/version/tz_version index 56debb8e..f89a121c 100644 --- a/output_data/version/tz_version +++ b/output_data/version/tz_version @@ -1 +1 @@ -007.001|2022a|001
\ No newline at end of file +007.001|2022g|001
\ No newline at end of file diff --git a/testing/data/test1/output_data/android/tzlookup.xml b/testing/data/test1/output_data/android/tzlookup.xml index a0b2fb1b..3a3bcaa3 100644 --- a/testing/data/test1/output_data/android/tzlookup.xml +++ b/testing/data/test1/output_data/android/tzlookup.xml @@ -129,10 +129,10 @@ <id alts="Brazil/DeNoronha">America/Noronha</id> <id alts="Brazil/East">America/Sao_Paulo</id> <id notafter="1550368800000" repl="America/Sao_Paulo">America/Bahia</id> - <id notafter="1214280000000" repl="America/Recife">America/Santarem</id> <id notafter="1330221600000" repl="America/Bahia">America/Recife</id> <id notafter="972180000000" repl="America/Recife">America/Fortaleza</id> <id notafter="1013911200000" repl="America/Recife">America/Belem</id> + <id notafter="1214280000000" repl="America/Recife">America/Santarem</id> <id notafter="824004000000" repl="America/Fortaleza">America/Maceio</id> <id notafter="1361066400000" repl="America/Bahia">America/Araguaina</id> <id alts="Brazil/West">America/Manaus</id> @@ -159,34 +159,30 @@ <id>America/Belize</id> </country> <country code="ca" default="America/Toronto" everutc="n"> - <id alts="America/Montreal,Canada/Eastern">America/Toronto</id> + <id alts="America/Montreal,America/Nipigon,America/Thunder_Bay,Canada/Eastern">America/Toronto</id> <id alts="Canada/Pacific">America/Vancouver</id> <id alts="Canada/Mountain">America/Edmonton</id> - <id alts="Canada/Central">America/Winnipeg</id> + <id alts="America/Rainy_River,Canada/Central">America/Winnipeg</id> <id alts="Canada/Atlantic">America/Halifax</id> <id alts="Canada/Newfoundland">America/St_Johns</id> <id notafter="1162098000000" repl="America/Halifax">America/Moncton</id> <id notafter="57733200000" repl="America/Halifax">America/Glace_Bay</id> <id notafter="1299996000000" repl="America/Halifax">America/Goose_Bay</id> <id>America/Blanc-Sablon</id> - <id notafter="120636000000" repl="America/Toronto">America/Thunder_Bay</id> - <id notafter="972802800000" repl="America/Toronto">America/Iqaluit</id> - <id notafter="89186400000" repl="America/Thunder_Bay">America/Nipigon</id> - <id notafter="796806000000" repl="America/Iqaluit">America/Pangnirtung</id> + <id notafter="972802800000" repl="America/Toronto" alts="America/Pangnirtung">America/Iqaluit</id> <id alts="America/Coral_Harbour">America/Atikokan</id> <id alts="Canada/Saskatchewan">America/Regina</id> <id notafter="73472400000" repl="America/Regina">America/Swift_Current</id> <id notafter="1130659200000" repl="America/Winnipeg">America/Rankin_Inlet</id> - <id notafter="986112000000" repl="America/Rankin_Inlet">America/Rainy_River</id> <id notafter="1173600000000" repl="America/Winnipeg">America/Resolute</id> - <id notafter="309945600000" repl="America/Edmonton">America/Yellowknife</id> + <id notafter="0" repl="America/Edmonton">America/Yellowknife</id> <id>America/Dawson_Creek</id> <id notafter="84013200000" repl="America/Dawson_Creek">America/Creston</id> <id notafter="1425808800000" repl="America/Dawson_Creek">America/Fort_Nelson</id> - <id notafter="294228000000" repl="America/Yellowknife">America/Inuvik</id> + <id notafter="294228000000" repl="America/Edmonton">America/Inuvik</id> <id notafter="986115600000" repl="America/Edmonton">America/Cambridge_Bay</id> - <id notafter="120646800000" repl="America/Whitehorse">America/Dawson</id> <id alts="Canada/Yukon">America/Whitehorse</id> + <id notafter="120646800000" repl="America/Whitehorse">America/Dawson</id> </country> <country code="cc" default="Indian/Cocos" everutc="n"> <id>Indian/Cocos</id> @@ -241,7 +237,7 @@ <id>Indian/Christmas</id> </country> <country code="cy" default="Asia/Nicosia" everutc="n"> - <id>Asia/Nicosia</id> + <id alts="Europe/Nicosia">Asia/Nicosia</id> <id>Asia/Famagusta</id> </country> <country code="cz" default="Europe/Prague" everutc="n"> @@ -441,7 +437,7 @@ </country> <country code="ki" default="Pacific/Tarawa" everutc="n"> <id>Pacific/Kiritimati</id> - <id alts="Pacific/Kanton">Pacific/Enderbury</id> + <id alts="Pacific/Enderbury">Pacific/Kanton</id> <id>Pacific/Tarawa</id> </country> <country code="km" default="Indian/Comoro" everutc="n"> @@ -536,8 +532,8 @@ <id alts="Asia/Rangoon">Asia/Yangon</id> </country> <country code="mn" default="Asia/Ulaanbaatar" everutc="n"> - <id notafter="1206889200000" repl="Asia/Ulaanbaatar">Asia/Choibalsan</id> <id alts="Asia/Ulan_Bator">Asia/Ulaanbaatar</id> + <id notafter="1206889200000" repl="Asia/Ulaanbaatar">Asia/Choibalsan</id> <id>Asia/Hovd</id> </country> <country code="mo" default="Asia/Macau" everutc="n"> @@ -571,18 +567,19 @@ <id alts="Mexico/General">America/Mexico_City</id> <id notafter="407653200000" repl="America/Mexico_City">America/Merida</id> <id notafter="594198000000" repl="America/Mexico_City">America/Monterrey</id> + <id notafter="1667116800000" repl="America/Mexico_City">America/Chihuahua</id> <id notafter="1270371600000" repl="America/Mexico_City">America/Bahia_Banderas</id> <id>America/Matamoros</id> + <id notafter="1667718000000" repl="America/Matamoros">America/Ojinaga</id> <id>America/Cancun</id> - <id>America/Chihuahua</id> - <id notafter="891766800000" repl="America/Chihuahua" alts="Mexico/BajaSur">America/Mazatlan</id> + <id>America/Ciudad_Juarez</id> <id>America/Hermosillo</id> - <id>America/Ojinaga</id> + <id notafter="1667116800000" repl="America/Hermosillo" alts="Mexico/BajaSur">America/Mazatlan</id> <id alts="America/Ensenada,America/Santa_Isabel,Mexico/BajaNorte">America/Tijuana</id> </country> <country code="my" default="Asia/Kuala_Lumpur" everutc="n"> <id>Asia/Kuala_Lumpur</id> - <id notafter="378664200000" repl="Asia/Kuala_Lumpur">Asia/Kuching</id> + <id notafter="378662400000" repl="Asia/Kuala_Lumpur">Asia/Kuching</id> </country> <country code="mz" default="Africa/Maputo" everutc="n"> <id>Africa/Maputo</id> @@ -815,7 +812,7 @@ <id>Pacific/Tongatapu</id> </country> <country code="tr" default="Europe/Istanbul" everutc="n"> - <id alts="Turkey">Europe/Istanbul</id> + <id alts="Asia/Istanbul,Turkey">Europe/Istanbul</id> </country> <country code="tt" default="America/Port_of_Spain" everutc="n"> <id alts="America/Virgin">America/Port_of_Spain</id> @@ -830,9 +827,7 @@ <id>Africa/Dar_es_Salaam</id> </country> <country code="ua" default="Europe/Kiev" everutc="n"> - <id>Europe/Kiev</id> - <id notafter="686102400000" repl="Europe/Kiev">Europe/Zaporozhye</id> - <id notafter="686091600000" repl="Europe/Zaporozhye">Europe/Uzhgorod</id> + <id alts="Europe/Kyiv,Europe/Uzhgorod,Europe/Zaporozhye">Europe/Kiev</id> <id picker="n">Europe/Simferopol</id> </country> <country code="ug" default="Africa/Kampala" everutc="n"> diff --git a/testing/data/test1/output_data/iana/tzdata b/testing/data/test1/output_data/iana/tzdata Binary files differindex 8d941d65..53852dc9 100644 --- a/testing/data/test1/output_data/iana/tzdata +++ b/testing/data/test1/output_data/iana/tzdata diff --git a/testing/data/test1/output_data/icu_overlay/icu_tzdata.dat b/testing/data/test1/output_data/icu_overlay/icu_tzdata.dat Binary files differindex c975cd15..a4b1ed58 100644 --- a/testing/data/test1/output_data/icu_overlay/icu_tzdata.dat +++ b/testing/data/test1/output_data/icu_overlay/icu_tzdata.dat diff --git a/testing/data/test3/output_data/android/tzlookup.xml b/testing/data/test3/output_data/android/tzlookup.xml index a0b2fb1b..3a3bcaa3 100644 --- a/testing/data/test3/output_data/android/tzlookup.xml +++ b/testing/data/test3/output_data/android/tzlookup.xml @@ -129,10 +129,10 @@ <id alts="Brazil/DeNoronha">America/Noronha</id> <id alts="Brazil/East">America/Sao_Paulo</id> <id notafter="1550368800000" repl="America/Sao_Paulo">America/Bahia</id> - <id notafter="1214280000000" repl="America/Recife">America/Santarem</id> <id notafter="1330221600000" repl="America/Bahia">America/Recife</id> <id notafter="972180000000" repl="America/Recife">America/Fortaleza</id> <id notafter="1013911200000" repl="America/Recife">America/Belem</id> + <id notafter="1214280000000" repl="America/Recife">America/Santarem</id> <id notafter="824004000000" repl="America/Fortaleza">America/Maceio</id> <id notafter="1361066400000" repl="America/Bahia">America/Araguaina</id> <id alts="Brazil/West">America/Manaus</id> @@ -159,34 +159,30 @@ <id>America/Belize</id> </country> <country code="ca" default="America/Toronto" everutc="n"> - <id alts="America/Montreal,Canada/Eastern">America/Toronto</id> + <id alts="America/Montreal,America/Nipigon,America/Thunder_Bay,Canada/Eastern">America/Toronto</id> <id alts="Canada/Pacific">America/Vancouver</id> <id alts="Canada/Mountain">America/Edmonton</id> - <id alts="Canada/Central">America/Winnipeg</id> + <id alts="America/Rainy_River,Canada/Central">America/Winnipeg</id> <id alts="Canada/Atlantic">America/Halifax</id> <id alts="Canada/Newfoundland">America/St_Johns</id> <id notafter="1162098000000" repl="America/Halifax">America/Moncton</id> <id notafter="57733200000" repl="America/Halifax">America/Glace_Bay</id> <id notafter="1299996000000" repl="America/Halifax">America/Goose_Bay</id> <id>America/Blanc-Sablon</id> - <id notafter="120636000000" repl="America/Toronto">America/Thunder_Bay</id> - <id notafter="972802800000" repl="America/Toronto">America/Iqaluit</id> - <id notafter="89186400000" repl="America/Thunder_Bay">America/Nipigon</id> - <id notafter="796806000000" repl="America/Iqaluit">America/Pangnirtung</id> + <id notafter="972802800000" repl="America/Toronto" alts="America/Pangnirtung">America/Iqaluit</id> <id alts="America/Coral_Harbour">America/Atikokan</id> <id alts="Canada/Saskatchewan">America/Regina</id> <id notafter="73472400000" repl="America/Regina">America/Swift_Current</id> <id notafter="1130659200000" repl="America/Winnipeg">America/Rankin_Inlet</id> - <id notafter="986112000000" repl="America/Rankin_Inlet">America/Rainy_River</id> <id notafter="1173600000000" repl="America/Winnipeg">America/Resolute</id> - <id notafter="309945600000" repl="America/Edmonton">America/Yellowknife</id> + <id notafter="0" repl="America/Edmonton">America/Yellowknife</id> <id>America/Dawson_Creek</id> <id notafter="84013200000" repl="America/Dawson_Creek">America/Creston</id> <id notafter="1425808800000" repl="America/Dawson_Creek">America/Fort_Nelson</id> - <id notafter="294228000000" repl="America/Yellowknife">America/Inuvik</id> + <id notafter="294228000000" repl="America/Edmonton">America/Inuvik</id> <id notafter="986115600000" repl="America/Edmonton">America/Cambridge_Bay</id> - <id notafter="120646800000" repl="America/Whitehorse">America/Dawson</id> <id alts="Canada/Yukon">America/Whitehorse</id> + <id notafter="120646800000" repl="America/Whitehorse">America/Dawson</id> </country> <country code="cc" default="Indian/Cocos" everutc="n"> <id>Indian/Cocos</id> @@ -241,7 +237,7 @@ <id>Indian/Christmas</id> </country> <country code="cy" default="Asia/Nicosia" everutc="n"> - <id>Asia/Nicosia</id> + <id alts="Europe/Nicosia">Asia/Nicosia</id> <id>Asia/Famagusta</id> </country> <country code="cz" default="Europe/Prague" everutc="n"> @@ -441,7 +437,7 @@ </country> <country code="ki" default="Pacific/Tarawa" everutc="n"> <id>Pacific/Kiritimati</id> - <id alts="Pacific/Kanton">Pacific/Enderbury</id> + <id alts="Pacific/Enderbury">Pacific/Kanton</id> <id>Pacific/Tarawa</id> </country> <country code="km" default="Indian/Comoro" everutc="n"> @@ -536,8 +532,8 @@ <id alts="Asia/Rangoon">Asia/Yangon</id> </country> <country code="mn" default="Asia/Ulaanbaatar" everutc="n"> - <id notafter="1206889200000" repl="Asia/Ulaanbaatar">Asia/Choibalsan</id> <id alts="Asia/Ulan_Bator">Asia/Ulaanbaatar</id> + <id notafter="1206889200000" repl="Asia/Ulaanbaatar">Asia/Choibalsan</id> <id>Asia/Hovd</id> </country> <country code="mo" default="Asia/Macau" everutc="n"> @@ -571,18 +567,19 @@ <id alts="Mexico/General">America/Mexico_City</id> <id notafter="407653200000" repl="America/Mexico_City">America/Merida</id> <id notafter="594198000000" repl="America/Mexico_City">America/Monterrey</id> + <id notafter="1667116800000" repl="America/Mexico_City">America/Chihuahua</id> <id notafter="1270371600000" repl="America/Mexico_City">America/Bahia_Banderas</id> <id>America/Matamoros</id> + <id notafter="1667718000000" repl="America/Matamoros">America/Ojinaga</id> <id>America/Cancun</id> - <id>America/Chihuahua</id> - <id notafter="891766800000" repl="America/Chihuahua" alts="Mexico/BajaSur">America/Mazatlan</id> + <id>America/Ciudad_Juarez</id> <id>America/Hermosillo</id> - <id>America/Ojinaga</id> + <id notafter="1667116800000" repl="America/Hermosillo" alts="Mexico/BajaSur">America/Mazatlan</id> <id alts="America/Ensenada,America/Santa_Isabel,Mexico/BajaNorte">America/Tijuana</id> </country> <country code="my" default="Asia/Kuala_Lumpur" everutc="n"> <id>Asia/Kuala_Lumpur</id> - <id notafter="378664200000" repl="Asia/Kuala_Lumpur">Asia/Kuching</id> + <id notafter="378662400000" repl="Asia/Kuala_Lumpur">Asia/Kuching</id> </country> <country code="mz" default="Africa/Maputo" everutc="n"> <id>Africa/Maputo</id> @@ -815,7 +812,7 @@ <id>Pacific/Tongatapu</id> </country> <country code="tr" default="Europe/Istanbul" everutc="n"> - <id alts="Turkey">Europe/Istanbul</id> + <id alts="Asia/Istanbul,Turkey">Europe/Istanbul</id> </country> <country code="tt" default="America/Port_of_Spain" everutc="n"> <id alts="America/Virgin">America/Port_of_Spain</id> @@ -830,9 +827,7 @@ <id>Africa/Dar_es_Salaam</id> </country> <country code="ua" default="Europe/Kiev" everutc="n"> - <id>Europe/Kiev</id> - <id notafter="686102400000" repl="Europe/Kiev">Europe/Zaporozhye</id> - <id notafter="686091600000" repl="Europe/Zaporozhye">Europe/Uzhgorod</id> + <id alts="Europe/Kyiv,Europe/Uzhgorod,Europe/Zaporozhye">Europe/Kiev</id> <id picker="n">Europe/Simferopol</id> </country> <country code="ug" default="Africa/Kampala" everutc="n"> diff --git a/testing/data/test3/output_data/iana/tzdata b/testing/data/test3/output_data/iana/tzdata Binary files differindex 8d941d65..53852dc9 100644 --- a/testing/data/test3/output_data/iana/tzdata +++ b/testing/data/test3/output_data/iana/tzdata diff --git a/testing/data/test3/output_data/icu_overlay/icu_tzdata.dat b/testing/data/test3/output_data/icu_overlay/icu_tzdata.dat Binary files differindex 0d3eb032..09f7bef5 100644 --- a/testing/data/test3/output_data/icu_overlay/icu_tzdata.dat +++ b/testing/data/test3/output_data/icu_overlay/icu_tzdata.dat |