Skip to content

Commit

Permalink
JodaOrg#524 DateTimeZone.forID() remains the same in mapping time zon…
Browse files Browse the repository at this point in the history
…e ids. DateTimeZone.forExactID() will return an object with an id exactly as provided
  • Loading branch information
Thomas Wolkenstein committed Oct 13, 2021
1 parent d2f1bb0 commit d88399d
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 5 deletions.
32 changes: 31 additions & 1 deletion src/main/java/org/joda/time/DateTimeZone.java
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,36 @@ public static DateTimeZone forID(String id) {
throw new IllegalArgumentException("The datetime zone id '" + id + "' is not recognised");
}

/**
* Same as {@link #forID(String) forID} but does not mapping of deprecated time zones.
*
* @param id the ID of the datetime zone, null means default
* @return the DateTimeZone object for the ID
* @throws IllegalArgumentException if the ID is not recognised
*/
public static DateTimeZone forExactID(String id) {
if (id == null) {
return getDefault();
}
if (id.equals("UTC")) {
return DateTimeZone.UTC;
}
DateTimeZone zone = getProvider().getExactZone(id);
if (zone != null) {
return zone;
}
if (id.startsWith("+") || id.startsWith("-")) {
int offset = parseOffset(id);
if (offset == 0L) {
return DateTimeZone.UTC;
} else {
id = printOffset(offset);
return fixedOffsetZone(id, offset);
}
}
throw new IllegalArgumentException("The datetime zone id '" + id + "' is not recognised");
}

/**
* Gets a time zone instance for the specified offset to UTC in hours.
* This method assumes standard length hours.
Expand Down Expand Up @@ -1261,7 +1291,7 @@ private void readObject(ObjectInputStream in) throws IOException {
}

private Object readResolve() throws ObjectStreamException {
return forID(iID);
return forExactID(iID);
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/main/java/org/joda/time/tz/Provider.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ public interface Provider {
*/
DateTimeZone getZone(String id);

/**
* Same as {@link #getZone(String) getZone} but does no mapping of deprecated time zones
*
* @param id String id
* @return null if not found
*/
DateTimeZone getExactZone(String id);

/**
* Returns an unmodifiable set of ids. All providers must at least
* support id "UTC".
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/org/joda/time/tz/UTCProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ public DateTimeZone getZone(String id) {
return null;
}

/**
* Returns {@link DateTimeZone#UTC UTC} for <code>"UTC"</code>, null
* otherwise.
*/
public DateTimeZone getExactZone(String id) {
if ("UTC".equalsIgnoreCase(id)) {
return DateTimeZone.UTC;
}
return null;
}

/**
* Returns a singleton collection containing only <code>"UTC"</code>.
*/
Expand Down
39 changes: 39 additions & 0 deletions src/main/java/org/joda/time/tz/ZoneInfoProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,45 @@ public DateTimeZone getZone(String id) {
return null;
}

if (obj instanceof Entry) {
// If this point is reached, mapping must link to another.
@SuppressWarnings("unchecked")
Entry<String, SoftReference<DateTimeZone>> entry = (Entry<String, SoftReference<DateTimeZone>>) obj;
return getZone(entry.getKey());
} else if (obj instanceof SoftReference<?>) {
@SuppressWarnings("unchecked")
SoftReference<DateTimeZone> ref = (SoftReference<DateTimeZone>) obj;
DateTimeZone tz = ref.get();
if (tz != null) {
return tz;
}
// Reference cleared; load data again.
return loadZoneData(id, id);
} else if (id.equals(obj)) {
// Load zone data for the first time.
return loadZoneData(id, id);
}

// If this point is reached, mapping must link to another.
return getZone((String) obj);
}

/**
* Returns a DateTimeZone object for the the id, that includes the exact id as provided, no mapping of deprecated zone ids is done as in {@code getZone}.
*
* @param id the id to load
* @return the loaded zone
*/
public DateTimeZone getExactZone(String id) {
if (id == null) {
return null;
}

Object obj = iZoneInfoMap.get(id);
if (obj == null) {
return null;
}

if (obj instanceof Entry) {
// If this point is reached, mapping must link to another.
@SuppressWarnings("unchecked")
Expand Down
15 changes: 15 additions & 0 deletions src/test/java/org/joda/time/TestDateTimeZone.java
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,9 @@ public Set getAvailableIDs() {
public DateTimeZone getZone(String id) {
return null;
}
public DateTimeZone getExactZone(String id) {
return null;
}
}
static class MockEmptyIDSProvider implements Provider {
public Set getAvailableIDs() {
Expand All @@ -610,6 +613,9 @@ public Set getAvailableIDs() {
public DateTimeZone getZone(String id) {
return null;
}
public DateTimeZone getExactZone(String id) {
return null;
}
}
static class MockNoUTCProvider implements Provider {
public Set getAvailableIDs() {
Expand All @@ -620,6 +626,9 @@ public Set getAvailableIDs() {
public DateTimeZone getZone(String id) {
return null;
}
public DateTimeZone getExactZone(String id) {
return null;
}
}
static class MockBadUTCProvider implements Provider {
public Set getAvailableIDs() {
Expand All @@ -631,6 +640,9 @@ public Set getAvailableIDs() {
public DateTimeZone getZone(String id) {
return null;
}
public DateTimeZone getExactZone(String id) {
return null;
}
}
static class MockOKProvider implements Provider {
public Set getAvailableIDs() {
Expand All @@ -642,6 +654,9 @@ public Set getAvailableIDs() {
public DateTimeZone getZone(String id) {
return DateTimeZone.UTC;
}
public DateTimeZone getExactZone(String id) {
return DateTimeZone.UTC;
}
}

//-----------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ public void test_printParseZoneGMT() {
DateTimeFormatter f = bld.toFormatter();

DateTime dt = new DateTime(2007, 3, 4, 12, 30, 0, DateTimeZone.forID("GMT"));
assertEquals("2007-03-04 12:30 GMT", f.print(dt));
assertEquals("2007-03-04 12:30 Etc/GMT", f.print(dt));
assertEquals(dt, f.parseDateTime("2007-03-04 12:30 GMT"));
}

Expand All @@ -501,7 +501,7 @@ public void test_printParseZoneGMT_suffix() {
DateTimeFormatter f = bld.toFormatter();

DateTime dt = new DateTime(2007, 3, 4, 12, 30, 0, DateTimeZone.forID("GMT"));
assertEquals("2007-03-04 12:30 GMT]", f.print(dt));
assertEquals("2007-03-04 12:30 Etc/GMT]", f.print(dt));
assertEquals(dt, f.parseDateTime("2007-03-04 12:30 GMT]"));
}

Expand Down
60 changes: 58 additions & 2 deletions src/test/java/org/joda/time/tz/TestCachedDateTimeZone.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,22 @@
*/
package org.joda.time.tz;

import org.joda.time.DateTimeZone;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
import java.time.ZoneId;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TimeZone;

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

import org.joda.time.DateTimeZone;

/**
* Test cases for FixedDateTimeZone.
*
Expand Down Expand Up @@ -55,6 +61,56 @@ protected void tearDown() throws Exception {
DateTimeZone.setDefault(originalDateTimeZone);
}

public void testRangoonDateTimeZone_MappingToNewId_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");
}

public void testRangoonDateTimeZone_NoMapping() throws Exception {
DateTimeZone zoneOld = DateTimeZone.forExactID("Asia/Rangoon");
assertEquals(zoneOld.getID(), "Asia/Rangoon");

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

public void testRangoonJavaUtilTimeZone() throws Exception {
TimeZone zone = TimeZone.getTimeZone("Asia/Rangoon");
assertEquals(zone.getID(), "Asia/Rangoon");

TimeZone zoneNew = TimeZone.getTimeZone("Asia/Yangon");
assertEquals(zoneNew.getID(), "Asia/Yangon");
}

public void testRangoonJavaTimeZoneId() throws Exception {
ZoneId zone = ZoneId.of("Asia/Rangoon");
assertEquals(zone.getId(), "Asia/Rangoon");

ZoneId zoneNew = ZoneId.of("Asia/Yangon");
assertEquals(zoneNew.getId(), "Asia/Yangon");
}

public void testRangoonCachingForMappingCode() throws Exception {
DateTimeZone zoneYangon = DateTimeZone.forID("Asia/Rangoon");
DateTimeZone zoneRangoon = DateTimeZone.forExactID("Asia/Rangoon");
Field field_iZoneInfoMap = ZoneInfoProvider.class.getDeclaredField("iZoneInfoMap");
field_iZoneInfoMap.setAccessible(true);
Map<String, Object> iZoneInfoMap = (Map<String, Object>) field_iZoneInfoMap.get(DateTimeZone.getProvider());
Entry<String, SoftReference<DateTimeZone>> entryRangoon = (Entry<String, SoftReference<DateTimeZone>>) iZoneInfoMap.get("Asia/Rangoon");
assertEquals("Asia/Yangon", entryRangoon.getKey());
SoftReference<DateTimeZone> entryYangon = (SoftReference<DateTimeZone>) iZoneInfoMap.get("Asia/Yangon");
entryRangoon.getValue().clear();
entryYangon.clear();

assertEquals(DateTimeZone.forID("Asia/Rangoon"), zoneYangon);
assertEquals(DateTimeZone.forExactID("Asia/Rangoon"), zoneRangoon);
assertEquals(DateTimeZone.forID("Asia/Rangoon").getID(), "Asia/Yangon");
assertEquals(DateTimeZone.forExactID("Asia/Rangoon").getID(), "Asia/Rangoon");
}

public void test_caching() throws Exception {
CachedDateTimeZone zone1 = CachedDateTimeZone.forZone(DateTimeZone.forID("Europe/Paris"));
CachedDateTimeZone zone2 = CachedDateTimeZone.forZone(DateTimeZone.forID("Europe/Paris"));
Expand Down

0 comments on commit d88399d

Please sign in to comment.