From a001c19cfd1c655bf5cdbc3066538410ee1cea06 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 19 Jul 2024 08:26:07 -0400 Subject: [PATCH 1/4] Add testLang1641() --- .../commons/lang3/time/FastDateFormatTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java b/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java index aa13e28453b..3007c515ef6 100644 --- a/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java +++ b/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java @@ -47,6 +47,9 @@ * Unit tests {@link org.apache.commons.lang3.time.FastDateFormat}. */ public class FastDateFormatTest extends AbstractLangTest { + + private static final String ISO_8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssZZ"; + private static final int NTHREADS = 10; private static final int NROUNDS = 10000; @@ -269,6 +272,20 @@ public void testLANG_954() { FastDateFormat.getInstance(pattern); } + @Test + public void testLang1641() { + assertSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT), FastDateFormat.getInstance(ISO_8601_DATE_FORMAT)); + // commons-lang's GMT TimeZone + assertSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, FastTimeZone.getGmtTimeZone()), + FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, FastTimeZone.getGmtTimeZone())); + // default TimeZone + assertSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getDefault()), + FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getDefault())); + // TimeZones that are identical in every way except ID + assertNotSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getTimeZone("Australia/Broken_Hill")), + FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getTimeZone("Australia/Yancowinna"))); + } + @Test public void testParseSync() throws InterruptedException { final String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS"; From abb0ca487cefc6d6df66600769655b3527a7f63e Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 19 Jul 2024 08:27:03 -0400 Subject: [PATCH 2/4] Rename some test methods --- .../lang3/time/FastDateFormatTest.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java b/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java index 3007c515ef6..698dd1ade4c 100644 --- a/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java +++ b/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java @@ -248,7 +248,7 @@ public void testDateDefaults() { } @Test - public void testLANG_1152() { + public void testLang1152() { final TimeZone utc = FastTimeZone.getGmtTimeZone(); final Date date = new Date(Long.MAX_VALUE); @@ -259,19 +259,10 @@ public void testLANG_1152() { assertEquals("17/08/292278994", dateAsString); } @Test - public void testLANG_1267() { + public void testLang1267() { FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); } - /** - * According to LANG-954 (https://issues.apache.org/jira/browse/LANG-954) this is broken in Android 2.1. - */ - @Test - public void testLANG_954() { - final String pattern = "yyyy-MM-dd'T'"; - FastDateFormat.getInstance(pattern); - } - @Test public void testLang1641() { assertSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT), FastDateFormat.getInstance(ISO_8601_DATE_FORMAT)); @@ -286,6 +277,15 @@ public void testLang1641() { FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getTimeZone("Australia/Yancowinna"))); } + /** + * According to LANG-954 (https://issues.apache.org/jira/browse/LANG-954) this is broken in Android 2.1. + */ + @Test + public void testLang954() { + final String pattern = "yyyy-MM-dd'T'"; + FastDateFormat.getInstance(pattern); + } + @Test public void testParseSync() throws InterruptedException { final String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS"; From c6d2ab2ba558cfb558574864655df68572c66e4b Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 7 Nov 2025 09:54:14 -0500 Subject: [PATCH 3/4] [LANG-1786] FastDateFormat logs warnings on the console using FastDateFormat on Java 25 - Add TimeZones.getTimeZone(String) to map deprecated ZoneId#SHORT_IDS - Avoids messages to System.err from the JRE's TimeZone.getTimeZone(String) starting on Java 25 - Calls to TimeZone.getTimeZone(String) are now delegated to TimeZones.getTimeZone(String) - You can disable mapping from ZoneId#SHORT_IDS by setting the system property "TimeZones.mapShortIDs=false" --- pom.xml | 13 +++++++- .../commons/lang3/time/FastDateParser.java | 30 +++++++++++++++---- .../commons/lang3/time/FastTimeZone.java | 2 +- .../apache/commons/lang3/time/TimeZones.java | 30 +++++++++++++++++-- .../commons/lang3/time/CalendarUtilsTest.java | 8 ++--- .../lang3/time/DateFormatUtilsTest.java | 22 +++++++------- .../commons/lang3/time/DateUtilsTest.java | 16 +++++----- .../lang3/time/DurationFormatUtilsTest.java | 2 +- .../lang3/time/FastDateFormatTest.java | 26 ++++++++-------- .../lang3/time/FastDateParserTest.java | 14 ++++----- .../time/FastDateParser_MoreOrLessTest.java | 2 +- .../FastDateParser_TimeZoneStrategyTest.java | 4 +-- .../lang3/time/FastDatePrinterTest.java | 14 ++++----- .../time/FastDatePrinterTimeZonesTest.java | 2 +- .../commons/lang3/time/FastTimeZoneTest.java | 4 +-- 15 files changed, 121 insertions(+), 68 deletions(-) diff --git a/pom.xml b/pom.xml index ee6b49e96d0..e1f5ddc00ef 100644 --- a/pom.xml +++ b/pom.xml @@ -162,7 +162,7 @@ scm:svn:https://dist.apache.org/repos/dist/dev/commons/lang true - 0.99 + 0.98 0.96 0.96 0.92 @@ -482,6 +482,17 @@ + + + java-25-up + + [25,) + + + + 0.99 + + benchmark diff --git a/src/main/java/org/apache/commons/lang3/time/FastDateParser.java b/src/main/java/org/apache/commons/lang3/time/FastDateParser.java index 4a7083052fd..2c90cabdcad 100644 --- a/src/main/java/org/apache/commons/lang3/time/FastDateParser.java +++ b/src/main/java/org/apache/commons/lang3/time/FastDateParser.java @@ -482,6 +482,7 @@ private StrategyAndWidth literal() { * A strategy that handles a time zone field in the parsing pattern */ static class TimeZoneStrategy extends PatternStrategy { + private static final class TzInfo { final TimeZone zone; final int dstOffset; @@ -496,6 +497,7 @@ public String toString() { return "TzInfo [zone=" + zone + ", dstOffset=" + dstOffset + "]"; } } + private static final String RFC_822_TIME_ZONE = "[+-]\\d{4}"; private static final String GMT_OPTION = TimeZones.GMT_ID + "[+-]\\d{1,2}:\\d{2}"; @@ -505,6 +507,22 @@ public String toString() { */ private static final int ID = 0; + /** + * Tests whether to skip the given time zone, true if TimeZone.getTimeZone(). + *

+ * On Java 25 and up, skips short IDs if {@code ignoreTimeZoneShortIDs} is true. + *

+ *

+ * This method is package private only for testing. + *

+ * + * @param tzId the ID to test. + * @return Whether to skip the given time zone ID. + */ + static boolean skipTimeZone(final String tzId) { + return tzId.equalsIgnoreCase(TimeZones.GMT_ID); + } + private final Locale locale; /** @@ -514,9 +532,9 @@ public String toString() { private final Map tzNames = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); /** - * Constructs a Strategy that parses a TimeZone + * Constructs a Strategy that parses a TimeZone. * - * @param locale The Locale + * @param locale The Locale. */ TimeZoneStrategy(final Locale locale) { this.locale = LocaleUtils.toLocale(locale); @@ -532,10 +550,10 @@ public String toString() { for (final String[] zoneNames : zones) { // offset 0 is the time zone ID and is not localized final String tzId = zoneNames[ID]; - if (tzId.equalsIgnoreCase(TimeZones.GMT_ID)) { + if (skipTimeZone(tzId)) { continue; } - final TimeZone tz = TimeZone.getTimeZone(tzId); + final TimeZone tz = TimeZones.getTimeZone(tzId); // offset 1 is long standard name // offset 2 is short standard name final TzInfo standard = new TzInfo(tz, false); @@ -561,10 +579,10 @@ public String toString() { } // Order is undefined. for (final String tzId : ArraySorter.sort(TimeZone.getAvailableIDs())) { - if (tzId.equalsIgnoreCase(TimeZones.GMT_ID)) { + if (skipTimeZone(tzId)) { continue; } - final TimeZone tz = TimeZone.getTimeZone(tzId); + final TimeZone tz = TimeZones.getTimeZone(tzId); final String zoneName = tz.getDisplayName(locale); if (sorted.add(zoneName)) { tzNames.put(zoneName, new TzInfo(tz, tz.observesDaylightTime())); diff --git a/src/main/java/org/apache/commons/lang3/time/FastTimeZone.java b/src/main/java/org/apache/commons/lang3/time/FastTimeZone.java index f7bc16a9381..7c252fec89b 100644 --- a/src/main/java/org/apache/commons/lang3/time/FastTimeZone.java +++ b/src/main/java/org/apache/commons/lang3/time/FastTimeZone.java @@ -77,7 +77,7 @@ public static TimeZone getTimeZone(final String id) { if (tz != null) { return tz; } - return TimeZone.getTimeZone(id); + return TimeZones.getTimeZone(id); } private static int parseInt(final String group) { diff --git a/src/main/java/org/apache/commons/lang3/time/TimeZones.java b/src/main/java/org/apache/commons/lang3/time/TimeZones.java index c63e6595cfb..b6717e639ec 100644 --- a/src/main/java/org/apache/commons/lang3/time/TimeZones.java +++ b/src/main/java/org/apache/commons/lang3/time/TimeZones.java @@ -17,9 +17,11 @@ package org.apache.commons.lang3.time; +import java.time.ZoneId; import java.util.TimeZone; import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.SystemProperties; /** * Helps dealing with {@link java.util.TimeZone}s. @@ -38,7 +40,32 @@ public class TimeZones { * * @since 3.13.0 */ - public static final TimeZone GMT = TimeZone.getTimeZone(GMT_ID); + public static final TimeZone GMT = TimeZones.getTimeZone(GMT_ID); + + /** + * Delegates to {@link TimeZone#getTimeZone(String)} after mapping an ID if it's in {@link ZoneId#SHORT_IDS}. + *

+ * On Java 25, calling {@link TimeZone#getTimeZone(String)} with an ID in {@link ZoneId#SHORT_IDS} writes a message to {@link System#err} in the form: + *

+ * + *
+     * WARNING: Use of the three-letter time zone ID "the-short-id" is deprecated and it will be removed in a future release
+     * 
+ *

+ * You can disable mapping from {@link ZoneId#SHORT_IDS} by setting the system property {@code "TimeZones.mapShortIDs=false"}. + *

+ * + * @param id Same as {@link TimeZone#getTimeZone(String)}. + * @return Same as {@link TimeZone#getTimeZone(String)}. + * @since 3.20.0 + */ + public static TimeZone getTimeZone(final String id) { + return TimeZone.getTimeZone(mapShortIDs() ? ZoneId.SHORT_IDS.getOrDefault(id, id) : id); + } + + private static boolean mapShortIDs() { + return SystemProperties.getBoolean(TimeZones.class, "mapShortIDs", () -> true); + } /** * Returns the given TimeZone if non-{@code null}, otherwise {@link TimeZone#getDefault()}. @@ -54,5 +81,4 @@ public static TimeZone toTimeZone(final TimeZone timeZone) { /** Do not instantiate. */ private TimeZones() { } - } diff --git a/src/test/java/org/apache/commons/lang3/time/CalendarUtilsTest.java b/src/test/java/org/apache/commons/lang3/time/CalendarUtilsTest.java index f5bf4fcd488..1010af6cfb1 100644 --- a/src/test/java/org/apache/commons/lang3/time/CalendarUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/time/CalendarUtilsTest.java @@ -98,7 +98,7 @@ void testGetYear() { */ @Test void testToLocalDate() { - final Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone(TimeZones.GMT_ID)); + final Calendar calendar = new GregorianCalendar(TimeZones.getTimeZone(TimeZones.GMT_ID)); calendar.setTimeInMillis(-27078001200000L); assertEquals("1111-12-08T05:00:00Z", calendar.toInstant().toString()); assertEquals(LocalDate.of(1111, Month.DECEMBER, 8), new CalendarUtils(calendar).toLocalDate()); @@ -109,7 +109,7 @@ void testToLocalDate() { @ParameterizedTest @MethodSource(TimeZonesTest.TIME_ZONE_GET_AVAILABLE_IDS) void testToLocalDateTime(final String timeZoneId) { - final TimeZone timeZone = TimeZone.getTimeZone(timeZoneId); + final TimeZone timeZone = TimeZones.getTimeZone(timeZoneId); final ZoneId zoneId = timeZone.toZoneId(); final Calendar calendar = new GregorianCalendar(timeZone); calendar.setTimeInMillis(0); @@ -122,7 +122,7 @@ void testToLocalDateTime(final String timeZoneId) { @ParameterizedTest @MethodSource(TimeZonesTest.TIME_ZONE_GET_AVAILABLE_IDS) void testToOffsetDateTime(final String timeZoneId) { - final TimeZone timeZone = TimeZone.getTimeZone(timeZoneId); + final TimeZone timeZone = TimeZones.getTimeZone(timeZoneId); final ZoneId zoneId = timeZone.toZoneId(); final Calendar calendar = new GregorianCalendar(timeZone); calendar.setTimeInMillis(0); @@ -135,7 +135,7 @@ void testToOffsetDateTime(final String timeZoneId) { @ParameterizedTest @MethodSource(TimeZonesTest.TIME_ZONE_GET_AVAILABLE_IDS) void testToZonedDateTime(final String timeZoneId) { - final TimeZone timeZone = TimeZone.getTimeZone(timeZoneId); + final TimeZone timeZone = TimeZones.getTimeZone(timeZoneId); final ZoneId zoneId = timeZone.toZoneId(); final Calendar calendar = new GregorianCalendar(timeZone); calendar.setTimeInMillis(0); diff --git a/src/test/java/org/apache/commons/lang3/time/DateFormatUtilsTest.java b/src/test/java/org/apache/commons/lang3/time/DateFormatUtilsTest.java index e6e442cdeed..25cbcc7f4c7 100644 --- a/src/test/java/org/apache/commons/lang3/time/DateFormatUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/time/DateFormatUtilsTest.java @@ -141,7 +141,7 @@ void testFormatUTC() { } private void testGmtMinus3(final String expectedValue, final String pattern) { - final TimeZone timeZone = TimeZone.getTimeZone("GMT-3"); + final TimeZone timeZone = TimeZones.getTimeZone("GMT-3"); assertFormats(expectedValue, pattern, timeZone, createFebruaryTestDate(timeZone)); } @@ -153,10 +153,10 @@ void testLANG1000() throws Exception { @Test void testLANG1462() { - final TimeZone timeZone = TimeZone.getTimeZone("GMT-3"); + final TimeZone timeZone = TimeZones.getTimeZone("GMT-3"); final Calendar calendar = createJuneTestDate(timeZone); assertEquals("20030608101112", DateFormatUtils.format(calendar, "yyyyMMddHHmmss")); - calendar.setTimeZone(TimeZone.getTimeZone("JST")); + calendar.setTimeZone(TimeZones.getTimeZone("JST")); assertEquals("20030608221112", DateFormatUtils.format(calendar, "yyyyMMddHHmmss")); } @@ -179,35 +179,35 @@ void testLang530() throws ParseException { @Test void testLang916() { - final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris")); + final Calendar cal = Calendar.getInstance(TimeZones.getTimeZone("Europe/Paris")); cal.clear(); cal.set(2009, 9, 16, 8, 42, 16); // Long. { - final String value = DateFormatUtils.format(cal.getTimeInMillis(), DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern(), TimeZone.getTimeZone("Europe/Paris")); + final String value = DateFormatUtils.format(cal.getTimeInMillis(), DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern(), TimeZones.getTimeZone("Europe/Paris")); assertEquals("2009-10-16T08:42:16+02:00", value, "long"); } { - final String value = DateFormatUtils.format(cal.getTimeInMillis(), DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern(), TimeZone.getTimeZone("Asia/Kolkata")); + final String value = DateFormatUtils.format(cal.getTimeInMillis(), DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern(), TimeZones.getTimeZone("Asia/Kolkata")); assertEquals("2009-10-16T12:12:16+05:30", value, "long"); } { - final String value = DateFormatUtils.format(cal.getTimeInMillis(), DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern(), TimeZone.getTimeZone("Europe/London")); + final String value = DateFormatUtils.format(cal.getTimeInMillis(), DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern(), TimeZones.getTimeZone("Europe/London")); assertEquals("2009-10-16T07:42:16+01:00", value, "long"); } // Calendar. { - final String value = DateFormatUtils.format(cal, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern(), TimeZone.getTimeZone("Europe/Paris")); + final String value = DateFormatUtils.format(cal, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern(), TimeZones.getTimeZone("Europe/Paris")); assertEquals("2009-10-16T08:42:16+02:00", value, "calendar"); } { - final String value = DateFormatUtils.format(cal, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern(), TimeZone.getTimeZone("Asia/Kolkata")); + final String value = DateFormatUtils.format(cal, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern(), TimeZones.getTimeZone("Asia/Kolkata")); assertEquals("2009-10-16T12:12:16+05:30", value, "calendar"); } { - final String value = DateFormatUtils.format(cal, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern(), TimeZone.getTimeZone("Europe/London")); + final String value = DateFormatUtils.format(cal, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern(), TimeZones.getTimeZone("Europe/London")); assertEquals("2009-10-16T07:42:16+01:00", value, "calendar"); } } @@ -215,7 +215,7 @@ void testLang916() { @DefaultLocale(language = "en") @Test void testSMTP() { - TimeZone timeZone = TimeZone.getTimeZone("GMT-3"); + TimeZone timeZone = TimeZones.getTimeZone("GMT-3"); Calendar june = createJuneTestDate(timeZone); assertFormats("Sun, 08 Jun 2003 10:11:12 -0300", DateFormatUtils.SMTP_DATETIME_FORMAT.getPattern(), diff --git a/src/test/java/org/apache/commons/lang3/time/DateUtilsTest.java b/src/test/java/org/apache/commons/lang3/time/DateUtilsTest.java index 5dac357771b..d4f7b0f5d81 100644 --- a/src/test/java/org/apache/commons/lang3/time/DateUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/time/DateUtilsTest.java @@ -66,9 +66,9 @@ @WritesDefaultLocale class DateUtilsTest extends AbstractLangTest { - private static final TimeZone TIME_ZONE_NY = TimeZone.getTimeZone("America/New_York"); + private static final TimeZone TIME_ZONE_NY = TimeZones.getTimeZone("America/New_York"); private static final TimeZone TIME_ZONE_DEFAULT = TimeZone.getDefault(); - private static final TimeZone TIME_ZONE_MET = TimeZone.getTimeZone("MET"); + private static final TimeZone TIME_ZONE_MET = TimeZones.getTimeZone("MET"); private static Date BASE_DATE; /** @@ -209,7 +209,7 @@ private static Stream testToLocalDateTimeTimeZone() { Arguments.of( LocalDateTime.of(2023, 1, 1, 14, 0), Date.from(LocalDateTime.of(2023, 1, 1, 0, 0).atOffset(ZoneOffset.UTC).toInstant()), - TimeZone.getTimeZone("Pacific/Kiritimati") + TimeZones.getTimeZone("Pacific/Kiritimati") ) ); // @formatter:on @@ -763,8 +763,8 @@ void testIsSameDay_DateNullNull() { @Test void testIsSameInstant_Cal() { - final GregorianCalendar cala = new GregorianCalendar(TimeZone.getTimeZone("GMT+1")); - final GregorianCalendar calb = new GregorianCalendar(TimeZone.getTimeZone("GMT-1")); + final GregorianCalendar cala = new GregorianCalendar(TimeZones.getTimeZone("GMT+1")); + final GregorianCalendar calb = new GregorianCalendar(TimeZones.getTimeZone("GMT-1")); cala.set(2004, Calendar.JULY, 9, 13, 45, 0); cala.set(Calendar.MILLISECOND, 0); calb.set(2004, Calendar.JULY, 9, 13, 45, 0); @@ -820,8 +820,8 @@ void testIsSameInstant_DateNullNull() { @Test void testIsSameLocalTime_Cal() { - final GregorianCalendar cala = new GregorianCalendar(TimeZone.getTimeZone("GMT+1")); - final GregorianCalendar calb = new GregorianCalendar(TimeZone.getTimeZone("GMT-1")); + final GregorianCalendar cala = new GregorianCalendar(TimeZones.getTimeZone("GMT+1")); + final GregorianCalendar calb = new GregorianCalendar(TimeZones.getTimeZone("GMT-1")); cala.set(2004, Calendar.JULY, 9, 13, 45, 0); cala.set(Calendar.MILLISECOND, 0); calb.set(2004, Calendar.JULY, 9, 13, 45, 0); @@ -1577,7 +1577,7 @@ void testTruncate_Bugzilla_31395() throws Exception { @Test void testTruncateLang59() { // Set TimeZone to Mountain Time - final TimeZone denverZone = TimeZone.getTimeZone("America/Denver"); + final TimeZone denverZone = TimeZones.getTimeZone("America/Denver"); TimeZone.setDefault(denverZone); final DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS XXX"); format.setTimeZone(denverZone); diff --git a/src/test/java/org/apache/commons/lang3/time/DurationFormatUtilsTest.java b/src/test/java/org/apache/commons/lang3/time/DurationFormatUtilsTest.java index 378b0ec2d36..b19911e6a9b 100644 --- a/src/test/java/org/apache/commons/lang3/time/DurationFormatUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/time/DurationFormatUtilsTest.java @@ -481,7 +481,7 @@ void testFormatPeriodeStartGreaterEnd() { @SuppressWarnings("deprecation") @Test void testFormatPeriodISO() { - final TimeZone timeZone = TimeZone.getTimeZone("GMT-3"); + final TimeZone timeZone = TimeZones.getTimeZone("GMT-3"); final Calendar base = Calendar.getInstance(timeZone); base.set(1970, Calendar.JANUARY, 1, 0, 0, 0); base.set(Calendar.MILLISECOND, 0); diff --git a/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java b/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java index 864c7ff44b0..08558c4ae70 100644 --- a/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java +++ b/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java @@ -157,12 +157,12 @@ void test_getInstance_String() { final FastDateFormat format1 = FastDateFormat.getInstance("MM/DD/yyyy"); final FastDateFormat format2 = FastDateFormat.getInstance("MM-DD-yyyy"); final FastDateFormat format3 = FastDateFormat.getInstance("MM-DD-yyyy"); - assertNotSame(format1, format2); assertSame(format2, format3); assertEquals("MM/DD/yyyy", format1.getPattern()); assertEquals(TimeZone.getDefault(), format1.getTimeZone()); assertEquals(TimeZone.getDefault(), format2.getTimeZone()); + assertNotNull(FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ssZ")); } @DefaultLocale(language = "en", country = "US") @@ -183,7 +183,7 @@ void test_getInstance_String_Locale() { void test_getInstance_String_TimeZone() { final FastDateFormat format1 = FastDateFormat.getInstance("MM/DD/yyyy", - TimeZone.getTimeZone("Atlantic/Reykjavik")); + TimeZones.getTimeZone("Atlantic/Reykjavik")); final FastDateFormat format2 = FastDateFormat.getInstance("MM/DD/yyyy"); final FastDateFormat format3 = FastDateFormat.getInstance("MM/DD/yyyy", TimeZone.getDefault()); final FastDateFormat format4 = FastDateFormat.getInstance("MM/DD/yyyy", TimeZone.getDefault()); @@ -191,7 +191,7 @@ void test_getInstance_String_TimeZone() { final FastDateFormat format6 = FastDateFormat.getInstance("MM-DD-yyyy"); assertNotSame(format1, format2); - assertEquals(TimeZone.getTimeZone("Atlantic/Reykjavik"), format1.getTimeZone()); + assertEquals(TimeZones.getTimeZone("Atlantic/Reykjavik"), format1.getTimeZone()); assertEquals(TimeZone.getDefault(), format2.getTimeZone()); assertSame(format3, format4); assertNotSame(format3, format5); @@ -203,13 +203,13 @@ void test_getInstance_String_TimeZone() { @Test void test_getInstance_String_TimeZone_Locale() { final FastDateFormat format1 = FastDateFormat.getInstance("MM/DD/yyyy", - TimeZone.getTimeZone("Atlantic/Reykjavik"), Locale.GERMANY); + TimeZones.getTimeZone("Atlantic/Reykjavik"), Locale.GERMANY); final FastDateFormat format2 = FastDateFormat.getInstance("MM/DD/yyyy", Locale.GERMANY); final FastDateFormat format3 = FastDateFormat.getInstance("MM/DD/yyyy", TimeZone.getDefault(), Locale.GERMANY); assertNotSame(format1, format2); - assertEquals(TimeZone.getTimeZone("Atlantic/Reykjavik"), format1.getTimeZone()); + assertEquals(TimeZones.getTimeZone("Atlantic/Reykjavik"), format1.getTimeZone()); assertEquals(TimeZone.getDefault(), format2.getTimeZone()); assertEquals(TimeZone.getDefault(), format3.getTimeZone()); assertEquals(Locale.GERMANY, format1.getLocale()); @@ -250,8 +250,8 @@ void testDateDefaults() { assertEquals(FastDateFormat.getDateInstance(FastDateFormat.LONG, Locale.CANADA), FastDateFormat.getDateInstance(FastDateFormat.LONG, TimeZone.getDefault(), Locale.CANADA)); - assertEquals(FastDateFormat.getDateInstance(FastDateFormat.LONG, TimeZone.getTimeZone("America/New_York")), - FastDateFormat.getDateInstance(FastDateFormat.LONG, TimeZone.getTimeZone("America/New_York"), Locale.getDefault())); + assertEquals(FastDateFormat.getDateInstance(FastDateFormat.LONG, TimeZones.getTimeZone("America/New_York")), + FastDateFormat.getDateInstance(FastDateFormat.LONG, TimeZones.getTimeZone("America/New_York"), Locale.getDefault())); assertEquals(FastDateFormat.getDateInstance(FastDateFormat.LONG), FastDateFormat.getDateInstance(FastDateFormat.LONG, TimeZone.getDefault(), Locale.getDefault())); @@ -283,8 +283,8 @@ void testLang1641() { assertSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getDefault()), FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getDefault())); // TimeZones that are identical in every way except ID - assertNotSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getTimeZone("Australia/Broken_Hill")), - FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getTimeZone("Australia/Yancowinna"))); + assertNotSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZones.getTimeZone("Australia/Broken_Hill")), + FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZones.getTimeZone("Australia/Yancowinna"))); } /** @@ -398,8 +398,8 @@ void testTimeDateDefaults() { assertEquals(FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM, Locale.CANADA), FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM, TimeZone.getDefault(), Locale.CANADA)); - assertEquals(FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM, TimeZone.getTimeZone("America/New_York")), - FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM, TimeZone.getTimeZone("America/New_York"), Locale.getDefault())); + assertEquals(FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM, TimeZones.getTimeZone("America/New_York")), + FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM, TimeZones.getTimeZone("America/New_York"), Locale.getDefault())); assertEquals(FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM), FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM, TimeZone.getDefault(), Locale.getDefault())); @@ -410,8 +410,8 @@ void testTimeDefaults() { assertEquals(FastDateFormat.getTimeInstance(FastDateFormat.LONG, Locale.CANADA), FastDateFormat.getTimeInstance(FastDateFormat.LONG, TimeZone.getDefault(), Locale.CANADA)); - assertEquals(FastDateFormat.getTimeInstance(FastDateFormat.LONG, TimeZone.getTimeZone("America/New_York")), - FastDateFormat.getTimeInstance(FastDateFormat.LONG, TimeZone.getTimeZone("America/New_York"), Locale.getDefault())); + assertEquals(FastDateFormat.getTimeInstance(FastDateFormat.LONG, TimeZones.getTimeZone("America/New_York")), + FastDateFormat.getTimeInstance(FastDateFormat.LONG, TimeZones.getTimeZone("America/New_York"), Locale.getDefault())); assertEquals(FastDateFormat.getTimeInstance(FastDateFormat.LONG), FastDateFormat.getTimeInstance(FastDateFormat.LONG, TimeZone.getDefault(), Locale.getDefault())); diff --git a/src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java b/src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java index 3369ff38287..3c6ecf0116f 100644 --- a/src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java +++ b/src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java @@ -103,9 +103,9 @@ private enum Expected1806 { private static final String MDY_DASH = "MM-DD-yyyy"; private static final String MDY_SLASH = "MM/DD/yyyy"; - private static final TimeZone REYKJAVIK = TimeZone.getTimeZone("Atlantic/Reykjavik"); - private static final TimeZone NEW_YORK = TimeZone.getTimeZone("America/New_York"); - private static final TimeZone INDIA = TimeZone.getTimeZone("Asia/Calcutta"); + private static final TimeZone REYKJAVIK = TimeZones.getTimeZone("Atlantic/Reykjavik"); + private static final TimeZone NEW_YORK = TimeZones.getTimeZone("America/New_York"); + private static final TimeZone INDIA = TimeZones.getTimeZone("Asia/Calcutta"); private static final Locale SWEDEN = new Locale("sv", "SE"); @@ -383,7 +383,7 @@ void testLANG_832(final TriFunction dpProv @ParameterizedTest @MethodSource(DATE_PARSER_PARAMETERS) void testLang1121(final TriFunction dpProvider) throws ParseException { - final TimeZone kst = TimeZone.getTimeZone("KST"); + final TimeZone kst = TimeZones.getTimeZone("KST"); final DateParser fdp = getInstance(dpProvider, "yyyyMMdd", kst, Locale.KOREA); assertThrows(ParseException.class, () -> fdp.parse("2015")); @@ -434,7 +434,7 @@ void testLang303() throws ParseException { void testLang538() throws ParseException { final DateParser parser = getInstance("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", TimeZones.GMT); - final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT-8")); + final Calendar cal = Calendar.getInstance(TimeZones.getTimeZone("GMT-8")); cal.clear(); cal.set(2009, Calendar.OCTOBER, 16, 8, 42, 16); @@ -591,12 +591,12 @@ void testParseZone(final TriFunction dpPro assertEquals(cal.getTime(), fdf.parse("2003-07-10T16:33:20.000 Eastern Daylight Time")); assertEquals(cal.getTime(), fdf.parse("2003-07-10T16:33:20.000 EDT")); - cal.setTimeZone(TimeZone.getTimeZone("GMT-3")); + cal.setTimeZone(TimeZones.getTimeZone("GMT-3")); cal.set(2003, Calendar.FEBRUARY, 10, 9, 0, 0); assertEquals(cal.getTime(), fdf.parse("2003-02-10T09:00:00.000 -0300")); - cal.setTimeZone(TimeZone.getTimeZone("GMT+5")); + cal.setTimeZone(TimeZones.getTimeZone("GMT+5")); cal.set(2003, Calendar.FEBRUARY, 10, 15, 5, 6); assertEquals(cal.getTime(), fdf.parse("2003-02-10T15:05:06.000 +0500")); diff --git a/src/test/java/org/apache/commons/lang3/time/FastDateParser_MoreOrLessTest.java b/src/test/java/org/apache/commons/lang3/time/FastDateParser_MoreOrLessTest.java index 79e31aa9657..77eae646a16 100644 --- a/src/test/java/org/apache/commons/lang3/time/FastDateParser_MoreOrLessTest.java +++ b/src/test/java/org/apache/commons/lang3/time/FastDateParser_MoreOrLessTest.java @@ -31,7 +31,7 @@ class FastDateParser_MoreOrLessTest extends AbstractLangTest { - private static final TimeZone NEW_YORK = TimeZone.getTimeZone("America/New_York"); + private static final TimeZone NEW_YORK = TimeZones.getTimeZone("America/New_York"); @Test void testInputHasLessCharacters() { diff --git a/src/test/java/org/apache/commons/lang3/time/FastDateParser_TimeZoneStrategyTest.java b/src/test/java/org/apache/commons/lang3/time/FastDateParser_TimeZoneStrategyTest.java index 8a4a137acae..99c3feaebf3 100644 --- a/src/test/java/org/apache/commons/lang3/time/FastDateParser_TimeZoneStrategyTest.java +++ b/src/test/java/org/apache/commons/lang3/time/FastDateParser_TimeZoneStrategyTest.java @@ -141,7 +141,7 @@ void testTimeZoneStrategy_TimeZone(final Locale locale) { private void testTimeZoneStrategyPattern(final String languageTag, final String source) throws ParseException { final Locale locale = Locale.forLanguageTag(languageTag); - final TimeZone timeZone = TimeZone.getTimeZone("Etc/UTC"); + final TimeZone timeZone = TimeZones.getTimeZone("Etc/UTC"); assumeFalse(LocaleUtils.isLanguageUndetermined(locale), () -> toFailureMessage(locale, languageTag, timeZone)); assumeTrue(LocaleUtils.isAvailableLocale(locale), () -> toFailureMessage(locale, languageTag, timeZone)); final FastDateParser parser = new FastDateParser("z", timeZone, locale); @@ -217,7 +217,7 @@ private void testTimeZoneStrategyPattern_TimeZone_getAvailableIDs(final Locale l assumeFalse(LocaleUtils.isLanguageUndetermined(locale), () -> toFailureMessage(locale, null, null)); assumeTrue(LocaleUtils.isAvailableLocale(locale), () -> toFailureMessage(locale, null, null)); for (final String id : ArraySorter.sort(TimeZone.getAvailableIDs())) { - final TimeZone timeZone = TimeZone.getTimeZone(id); + final TimeZone timeZone = TimeZones.getTimeZone(id); final String displayName = timeZone.getDisplayName(locale); final FastDateParser parser = new FastDateParser("z", timeZone, locale); try { diff --git a/src/test/java/org/apache/commons/lang3/time/FastDatePrinterTest.java b/src/test/java/org/apache/commons/lang3/time/FastDatePrinterTest.java index cb8c9deca01..2f25f26b439 100644 --- a/src/test/java/org/apache/commons/lang3/time/FastDatePrinterTest.java +++ b/src/test/java/org/apache/commons/lang3/time/FastDatePrinterTest.java @@ -59,8 +59,8 @@ private enum Expected1806 { } private static final String YYYY_MM_DD = "yyyy/MM/dd"; - private static final TimeZone NEW_YORK = TimeZone.getTimeZone("America/New_York"); - private static final TimeZone INDIA = TimeZone.getTimeZone("Asia/Calcutta"); + private static final TimeZone NEW_YORK = TimeZones.getTimeZone("America/New_York"); + private static final TimeZone INDIA = TimeZones.getTimeZone("Asia/Calcutta"); private static final Locale SWEDEN = new Locale("sv", "SE"); @@ -259,7 +259,7 @@ void testLang303() { void testLang538() { // more commonly constructed with: cal = new GregorianCalendar(2009, 9, 16, 8, 42, 16) // for the unit test to work in any time zone, constructing with GMT-8 rather than default locale time zone - final GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT-8")); + final GregorianCalendar cal = new GregorianCalendar(TimeZones.getTimeZone("GMT-8")); cal.clear(); cal.set(2009, Calendar.OCTOBER, 16, 8, 42, 16); @@ -289,21 +289,21 @@ void testLang645() { @Test void testLang916() { - final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris")); + final Calendar cal = Calendar.getInstance(TimeZones.getTimeZone("Europe/Paris")); cal.clear(); cal.set(2009, 9, 16, 8, 42, 16); // calendar fast. { - final String value = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss Z", TimeZone.getTimeZone("Europe/Paris")).format(cal); + final String value = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss Z", TimeZones.getTimeZone("Europe/Paris")).format(cal); assertEquals("2009-10-16T08:42:16 +0200", value, "calendar"); } { - final String value = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss Z", TimeZone.getTimeZone("Asia/Kolkata")).format(cal); + final String value = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss Z", TimeZones.getTimeZone("Asia/Kolkata")).format(cal); assertEquals("2009-10-16T12:12:16 +0530", value, "calendar"); } { - final String value = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss Z", TimeZone.getTimeZone("Europe/London")).format(cal); + final String value = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss Z", TimeZones.getTimeZone("Europe/London")).format(cal); assertEquals("2009-10-16T07:42:16 +0100", value, "calendar"); } } diff --git a/src/test/java/org/apache/commons/lang3/time/FastDatePrinterTimeZonesTest.java b/src/test/java/org/apache/commons/lang3/time/FastDatePrinterTimeZonesTest.java index fd046d053f1..c09726e9636 100644 --- a/src/test/java/org/apache/commons/lang3/time/FastDatePrinterTimeZonesTest.java +++ b/src/test/java/org/apache/commons/lang3/time/FastDatePrinterTimeZonesTest.java @@ -32,7 +32,7 @@ class FastDatePrinterTimeZonesTest extends AbstractLangTest { private static final String PATTERN = "h:mma z"; public static Stream data() { - return Stream.of(TimeZone.getAvailableIDs()).map(TimeZone::getTimeZone); + return Stream.of(TimeZone.getAvailableIDs()).map(TimeZones::getTimeZone); } @ParameterizedTest diff --git a/src/test/java/org/apache/commons/lang3/time/FastTimeZoneTest.java b/src/test/java/org/apache/commons/lang3/time/FastTimeZoneTest.java index 08a883506b1..6135cebfaa6 100644 --- a/src/test/java/org/apache/commons/lang3/time/FastTimeZoneTest.java +++ b/src/test/java/org/apache/commons/lang3/time/FastTimeZoneTest.java @@ -18,8 +18,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import java.util.TimeZone; - import org.apache.commons.lang3.AbstractLangTest; import org.junit.jupiter.api.Test; @@ -71,7 +69,7 @@ void testHoursMinutes() { @Test void testOlson() { - assertEquals(TimeZone.getTimeZone("America/New_York"), FastTimeZone.getTimeZone("America/New_York")); + assertEquals(TimeZones.getTimeZone("America/New_York"), FastTimeZone.getTimeZone("America/New_York")); } @Test From 19cc5e00b07feec8306ef96e83a594a17b79a54b Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 7 Nov 2025 10:03:13 -0500 Subject: [PATCH 4/4] [LANG-1786] FastDateFormat logs warnings on the console using FastDateFormat on Java 25 - Only enable on Java 25 and up --- src/main/java/org/apache/commons/lang3/time/TimeZones.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/lang3/time/TimeZones.java b/src/main/java/org/apache/commons/lang3/time/TimeZones.java index b6717e639ec..876b467c1ed 100644 --- a/src/main/java/org/apache/commons/lang3/time/TimeZones.java +++ b/src/main/java/org/apache/commons/lang3/time/TimeZones.java @@ -20,8 +20,10 @@ import java.time.ZoneId; import java.util.TimeZone; +import org.apache.commons.lang3.JavaVersion; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.SystemProperties; +import org.apache.commons.lang3.SystemUtils; /** * Helps dealing with {@link java.util.TimeZone}s. @@ -42,6 +44,8 @@ public class TimeZones { */ public static final TimeZone GMT = TimeZones.getTimeZone(GMT_ID); + private static final boolean JAVA_25 = SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_25); + /** * Delegates to {@link TimeZone#getTimeZone(String)} after mapping an ID if it's in {@link ZoneId#SHORT_IDS}. *

@@ -60,7 +64,7 @@ public class TimeZones { * @since 3.20.0 */ public static TimeZone getTimeZone(final String id) { - return TimeZone.getTimeZone(mapShortIDs() ? ZoneId.SHORT_IDS.getOrDefault(id, id) : id); + return TimeZone.getTimeZone(JAVA_25 && mapShortIDs() ? ZoneId.SHORT_IDS.getOrDefault(id, id) : id); } private static boolean mapShortIDs() {