diff --git a/src/main/java/org/joda/time/DateTimeZone.java b/src/main/java/org/joda/time/DateTimeZone.java index 735c3ad7c..549522d55 100644 --- a/src/main/java/org/joda/time/DateTimeZone.java +++ b/src/main/java/org/joda/time/DateTimeZone.java @@ -215,11 +215,13 @@ public static void setDefault(DateTimeZone zone) throws SecurityException { *

* The time zone id may be one of those returned by getAvailableIDs. * Short ids, as accepted by {@link java.util.TimeZone}, are not accepted. - * All IDs must be specified in the long format. - * The exception is UTC, which is an acceptable id. + * All IDs must be specified in the long format unless detailed below. *

- * Alternatively a locale independent, fixed offset, datetime zone can - * be specified. The form [+-]hh:mm can be used. + * A locale independent, fixed offset, datetime zone can be specified + * using the form [+-]hh:mm. + * The offset may be prefixed by 'UTC', 'GMT' or 'UT'. + * In addition, the IDs 'Z', 'UTC', 'GMT' and 'UT' will return a UTC + * equivalent time-zone. * * @param id the ID of the datetime zone, null means default * @return the DateTimeZone object for the ID @@ -237,13 +239,25 @@ public static DateTimeZone forID(String id) { if (zone != null) { return zone; } - if (id.startsWith("+") || id.startsWith("-")) { - int offset = parseOffset(id); + // compatibility with more ZoneId values + // note that GMT normally matches to Etc/GMT in the block above, but if the + // time-zone provider has been replaced and does not match GMT then this line will + if (id.equals("UT") || id.equals("GMT") || id.equals("Z")) { + return DateTimeZone.UTC; + } + String idToParse = id; + if (id.startsWith("UTC+") || id.startsWith("UTC-") || id.startsWith("GMT+") || id.startsWith("GMT-")) { + idToParse = id.substring(3); + } else if (id.startsWith("UT+") || id.startsWith("UT-")) { + idToParse = id.substring(2); + } + if (idToParse.startsWith("+") || idToParse.startsWith("-")) { + int offset = parseOffset(idToParse); if (offset == 0L) { return DateTimeZone.UTC; } else { - id = printOffset(offset); - return fixedOffsetZone(id, offset); + idToParse = printOffset(offset); + return fixedOffsetZone(idToParse, offset); } } throw new IllegalArgumentException("The datetime zone id '" + id + "' is not recognised"); diff --git a/src/test/java/org/joda/time/TestDateTimeZone.java b/src/test/java/org/joda/time/TestDateTimeZone.java index 642018ada..40eb1acae 100644 --- a/src/test/java/org/joda/time/TestDateTimeZone.java +++ b/src/test/java/org/joda/time/TestDateTimeZone.java @@ -205,17 +205,36 @@ public void testForID_String() { zone = DateTimeZone.forID("UTC"); assertSame(DateTimeZone.UTC, zone); + zone = DateTimeZone.forID("UT"); + assertSame(DateTimeZone.UTC, zone); + + zone = DateTimeZone.forID("Z"); + assertSame(DateTimeZone.UTC, zone); + + zone = DateTimeZone.forID("GMT"); + // depends if the default time-zone provider has been changed or not + assertTrue(zone == DateTimeZone.forID("Etc/GMT") || zone == DateTimeZone.UTC); + zone = DateTimeZone.forID("+00:00"); assertSame(DateTimeZone.UTC, zone); zone = DateTimeZone.forID("+00"); assertSame(DateTimeZone.UTC, zone); + long expected = DateTimeConstants.MILLIS_PER_HOUR + (23L * DateTimeConstants.MILLIS_PER_MINUTE); zone = DateTimeZone.forID("+01:23"); assertEquals("+01:23", zone.getID()); - assertEquals(DateTimeConstants.MILLIS_PER_HOUR + (23L * DateTimeConstants.MILLIS_PER_MINUTE), - zone.getOffset(TEST_TIME_SUMMER)); - + assertEquals(expected, zone.getOffset(TEST_TIME_SUMMER)); + zone = DateTimeZone.forID("GMT+01:23"); + assertEquals("+01:23", zone.getID()); + assertEquals(expected, zone.getOffset(TEST_TIME_SUMMER)); + zone = DateTimeZone.forID("UTC+01:23"); + assertEquals("+01:23", zone.getID()); + assertEquals(expected, zone.getOffset(TEST_TIME_SUMMER)); + zone = DateTimeZone.forID("UT+01:23"); + assertEquals("+01:23", zone.getID()); + assertEquals(expected, zone.getOffset(TEST_TIME_SUMMER)); + zone = DateTimeZone.forID("-02:00"); assertEquals("-02:00", zone.getID()); assertEquals((-2L * DateTimeConstants.MILLIS_PER_HOUR),