Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not resolve most zone IDs #676

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/main/java/org/joda/time/DateTimeZone.java
Original file line number Diff line number Diff line change
@@ -1198,8 +1198,19 @@ public long adjustOffset(long instant, boolean earlierOrLater) {
*
* @return the closest matching TimeZone object
*/
public java.util.TimeZone toTimeZone() {
return java.util.TimeZone.getTimeZone(iID);
public TimeZone toTimeZone() {
TimeZone converted = TimeZone.getTimeZone(iID);
// handle recent renames (since 2019) where the JDK may not have been updated yet
if (converted.getID().equals("GMT")) {
if (iID.equals("Europe/Kyiv")) {
converted = TimeZone.getTimeZone("Europe/Kiev");
} else if (iID.equals("Pacific/Kanton")) {
converted = TimeZone.getTimeZone("Pacific/Enderbury");
} else if (iID.equals("America/Nuuk")) {
converted = TimeZone.getTimeZone("America/Godthab");
}
}
return converted;
}

/**
148 changes: 144 additions & 4 deletions src/main/java/org/joda/time/tz/ZoneInfoCompiler.java
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@@ -61,6 +62,143 @@
* @since 1.0
*/
public class ZoneInfoCompiler {

private static final List<String> ANCIENT_IDS = Arrays.asList(
// changed in 1993
"Australia/ACT",
"Australia/LHI",
"Australia/NSW",
"Australia/North",
"Australia/Queensland",
"Australia/South",
"Australia/Tasmania",
"Australia/Victoria",
"Australia/West",
"Australia/Yancowinna",
"Brazil/Acre",
"Brazil/DeNoronha",
"Brazil/East",
"Brazil/West",
"Canada/Atlantic",
"Canada/Central",
"Canada/Eastern",
"Canada/Mountain",
"Canada/Newfoundland",
"Canada/Pacific",
"Canada/Saskatchewan",
"Canada/Yukon",
"Chile/Continental",
"Chile/EasterIsland",
"Cuba",
"Egypt",
"Eire",
"Etc/GMT+0",
"Etc/GMT-0",
"Etc/GMT0",
"Etc/Greenwich",
"Etc/UCT",
"Etc/Universal",
"Etc/Zulu",
"GB",
"GB-Eire",
"GMT+0",
"GMT-0",
"GMT0",
"GMT",
"Greenwich",
"Hongkong",
"Iceland",
"Iran",
"Israel",
"Jamaica",
"Japan",
"Kwajalein",
"Libya",
"Mexico/BajaNorte",
"Mexico/BajaSur",
"Mexico/General",
"NZ",
"NZ-CHAT",
"Navajo",
"PRC",
"Poland",
"Portugal",
"ROC",
"ROK",
"Singapore",
"Turkey",
"UCT",
"US/Alaska",
"US/Aleutian",
"US/Arizona",
"US/Central",
"US/East-Indiana",
"US/Eastern",
"US/Hawaii",
"US/Indiana-Starke",
"US/Michigan",
"US/Mountain",
"US/Pacific",
"US/Samoa",
"UCT",
"UTC",
"Universal",
"W-SU",
"Zulu",
// removed
"US/Pacific-New");

// allowing these to be "good links"
// all these follow the modern naming convention that avoids country names
// Australia/Canberra
// America/Buenos_Aires
// America/Catamarca
// America/Cordoba
// America/Indianapolis
// America/Jujuy
// America/Knox_IN
// America/Louisville
// America/Mendoza
// America/Virgin
// Pacific/Samoa
// Africa/Asmera
// Africa/Timbuktu
// America/Argentina/ComodRivadavia
// America/Atka
// America/Coral_Harbour
// America/Ensenada
// America/Fort_Wayne
// America/Godthab
// America/Montreal
// America/Porto_Acre
// America/Rosario
// America/Santa_Isabel
// America/Shiprock
// Antarctica/South_Pole
// Asia/Ashkhabad
// Asia/Calcutta
// Asia/Chongqing
// Asia/Chungking
// Asia/Dacca
// Asia/Harbin
// Asia/Kashgar
// Asia/Katmandu
// Asia/Macao
// Asia/Rangoon
// Asia/Saigon
// Asia/Tel_Aviv
// Asia/Thimbu
// Asia/Ujung_Pandang
// Asia/Ulan_Bator
// Atlantic/Faeroe
// Atlantic/Jan_Mayen
// Europe/Belfast
// Europe/Tiraspol
// Pacific/Johnston
// Pacific/Ponape
// Pacific/Truk
// Pacific/Yap

static DateTimeOfYear cStartOfYear;

static Chronology cLenientISO;
@@ -353,15 +491,17 @@ static boolean test(String id, DateTimeZone tz) {
public ZoneInfoCompiler() {
iRuleSets = new HashMap<String, RuleSet>();
iZones = new ArrayList<Zone>();
iGoodLinks = new ArrayList<String>();
iBackLinks = new ArrayList<String>();
iGoodLinks = new ArrayList<String>(); // list of pairs, (good, bad)*
iBackLinks = new ArrayList<String>(); // list of pairs, (good, bad)*
}

/**
* Returns a map of ids to DateTimeZones.
*
* @param outputDir optional directory to write compiled data files to
* @param sources optional list of source files to parse
* @return the map of ID to zone
* @throws IOException if an IO error occurs
*/
public Map<String, DateTimeZone> compile(File outputDir, File[] sources) throws IOException {
if (sources != null) {
@@ -430,7 +570,7 @@ public Map<String, DateTimeZone> compile(File outputDir, File[] sources) throws
}
}

// store "back" links as aliases (where name is permanently mapped
// store "back" links as aliases (where name is permanently mapped)
for (int pass = 0; pass < 2; pass++) {
for (int i = 0; i < iBackLinks.size(); i += 2) {
String id = iBackLinks.get(i);
@@ -551,7 +691,7 @@ public void parseDataFile(BufferedReader in, boolean backward) throws IOExceptio
// links in "backward" are deprecated names
// links in other files should be kept
// special case a few to try to repair terrible damage to tzdb
if (backward || alias.equals("US/Pacific-New") || alias.startsWith("Etc/") || alias.equals("GMT")) {
if (alias.startsWith("Etc/") || ANCIENT_IDS.contains(alias)) {
iBackLinks.add(real);
iBackLinks.add(alias);
} else {
25 changes: 13 additions & 12 deletions src/test/java/org/joda/time/TestDateTimeZone.java
Original file line number Diff line number Diff line change
@@ -1052,9 +1052,19 @@ public void testIsLocalDateTimeGap_NewYork() {

//-----------------------------------------------------------------------
public void testToTimeZone() {
DateTimeZone zone = DateTimeZone.forID("Europe/Paris");
TimeZone tz = zone.toTimeZone();
assertEquals("Europe/Paris", tz.getID());
assertEquals("Europe/Paris", DateTimeZone.forID("Europe/Paris").toTimeZone().getID());

String kanton = DateTimeZone.forID("Pacific/Kanton").toTimeZone().getID();
assertTrue(kanton.equals("Pacific/Kanton") || kanton.equals("Pacific/Enderbury"));
System.out.println(kanton);

String gothab = DateTimeZone.forID("America/Nuuk").toTimeZone().getID();
assertTrue(gothab.equals("America/Nuuk") || gothab.equals("America/Godthab"));
System.out.println(gothab);

String kyiv = DateTimeZone.forID("Europe/Kyiv").toTimeZone().getID();
assertTrue(kyiv.equals("Europe/Kyiv") || kyiv.equals("Europe/Kiev"));
System.out.println(kyiv);
}

//-----------------------------------------------------------------------
@@ -1323,13 +1333,4 @@ public void testPatchedNameKeysGazaHistoric() throws Exception {
assertEquals(false, str1.equals(str2));
}

//-----------------------------------------------------------------------
public void testIdNotAutoMapped_Asia_Yangon() throws Exception {
DateTimeZone zoneOld = DateTimeZone.forID("Asia/Rangoon");
assertEquals(zoneOld.getID(), "Asia/Yangon");

DateTimeZone zoneNew = DateTimeZone.forID("Asia/Yangon");
assertEquals(zoneNew.getID(), "Asia/Yangon");
}

}
62 changes: 58 additions & 4 deletions src/test/java/org/joda/time/tz/TestCompiler.java
Original file line number Diff line number Diff line change
@@ -16,21 +16,24 @@
package org.joda.time.tz;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.StringTokenizer;
import java.nio.charset.Charset;
import java.util.NoSuchElementException;

import junit.framework.TestCase;
import junit.framework.TestSuite;
import java.util.StringTokenizer;

import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
import org.joda.time.DateTimeZone;
import org.joda.time.tz.ZoneInfoCompiler.DateTimeOfYear;

import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
* Test cases for ZoneInfoCompiler.
*
@@ -136,6 +139,57 @@ public void testCompile() throws Exception {
TestBuilder.testReverseTransitions(tz, TestBuilder.AMERICA_LOS_ANGELES_DATA);
}

public void testCompileAllTzdb() throws Exception {
String[] files = {
"src/main/java/org/joda/time/tz/src/africa",
"src/main/java/org/joda/time/tz/src/antarctica",
"src/main/java/org/joda/time/tz/src/asia",
"src/main/java/org/joda/time/tz/src/australasia",
"src/main/java/org/joda/time/tz/src/europe",
"src/main/java/org/joda/time/tz/src/northamerica",
"src/main/java/org/joda/time/tz/src/southamerica",
"src/main/java/org/joda/time/tz/src/etcetera",
"src/main/java/org/joda/time/tz/src/backward",
};
StringBuilder buf = new StringBuilder();
for (int i = 0; i < files.length; i++) {
byte[] bytes = readAllBytes(files[i]);
buf.append(new String(bytes, Charset.forName("UTF-8")));
}

Provider provider = compileAndLoad(buf.toString());

// check some links
assertEquals("Europe/Kiev", provider.getZone("Europe/Kiev").getID());
assertEquals("Europe/Kyiv", provider.getZone("Europe/Kyiv").getID());
assertEquals("Asia/Rangoon", provider.getZone("Asia/Rangoon").getID());
assertEquals("Asia/Yangon", provider.getZone("Asia/Yangon").getID());
assertEquals("Europe/Lisbon", provider.getZone("Portugal").getID());
assertEquals("Africa/Tripoli", provider.getZone("Libya").getID());
assertEquals("Etc/GMT", provider.getZone("GMT").getID());
assertEquals("Etc/GMT", provider.getZone("Etc/GMT").getID());
assertEquals("Etc/GMT", provider.getZone("Etc/GMT0").getID());
assertEquals("Etc/GMT+1", provider.getZone("Etc/GMT+1").getID());
assertEquals("UTC", provider.getZone("UTC").getID());
assertEquals("Etc/UTC", provider.getZone("Etc/UTC").getID());
assertEquals("Australia/Currie", provider.getZone("Australia/Currie").getID());
}

private static byte[] readAllBytes(String fileName) throws IOException {
InputStream in = new FileInputStream(fileName);
try {
byte[] b = new byte[1024];
ByteArrayOutputStream out = new ByteArrayOutputStream();
int c;
while ((c = in.read(b)) != -1) {
out.write(b, 0, c);
}
return out.toByteArray();
} finally {
in.close();
}
}

public void testCompileOnBrokenTimeZoneFile() throws Exception {
try {
Provider provider = compileAndLoad(BROKEN_TIMEZONE_FILE);