From 1dfda7058ee127d4c112acf0a082b8974418745f Mon Sep 17 00:00:00 2001 From: rootvector2 Date: Tue, 9 Jun 2026 17:34:53 +0530 Subject: [PATCH] use Locale.ENGLISH when parsing dates in Converter.DATE --- .../java/org/apache/commons/cli/Converter.java | 3 ++- .../org/apache/commons/cli/ConverterTests.java | 14 +++++++++++++- .../commons/cli/PatternOptionBuilderTest.java | 3 ++- .../org/apache/commons/cli/TypeHandlerTest.java | 3 ++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/apache/commons/cli/Converter.java b/src/main/java/org/apache/commons/cli/Converter.java index 7e92c32f0..02fbc6f71 100644 --- a/src/main/java/org/apache/commons/cli/Converter.java +++ b/src/main/java/org/apache/commons/cli/Converter.java @@ -24,6 +24,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Locale; /** * The definition of the functional interface to call when doing a conversion. Like {@code Function} but can throw an Exception. @@ -76,7 +77,7 @@ public interface Converter { /** * Converts to a date using the format string Form "EEE MMM dd HH:mm:ss zzz yyyy". */ - Converter DATE = s -> new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy").parse(s); + Converter DATE = s -> new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH).parse(s); /** * Applies the conversion function to the String argument. diff --git a/src/test/java/org/apache/commons/cli/ConverterTests.java b/src/test/java/org/apache/commons/cli/ConverterTests.java index 8691d0757..f4471893e 100644 --- a/src/test/java/org/apache/commons/cli/ConverterTests.java +++ b/src/test/java/org/apache/commons/cli/ConverterTests.java @@ -26,12 +26,14 @@ Licensed to the Apache Software Foundation (ASF) under one or more import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Locale; import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.junitpioneer.jupiter.DefaultLocale; /** * Tests for standard Converters. @@ -84,13 +86,23 @@ void testDate() throws Exception { * time zone. */ final Date expected = new Date(1023400137000L); - final DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy"); + final DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH); final String formatted = dateFormat.format(expected); assertEquals(expected, Converter.DATE.apply(formatted)); assertThrows(java.text.ParseException.class, () -> Converter.DATE.apply("Jun 06 17:48:57 EDT 2002")); } + @Test + @DefaultLocale(language = "de", country = "DE") + void testDateLocaleIndependent() throws Exception { + // Date.toString() always emits English month/day names, so the converter must parse + // them even when the JVM default locale is not English. + final Date expected = new Date(1023400137000L); + final String formatted = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH).format(expected); + assertEquals(expected, Converter.DATE.apply(formatted)); + } + @Test void testFile() throws Exception { final URL url = this.getClass().getClassLoader().getResource("./org/apache/commons/cli/existing-readable.file"); diff --git a/src/test/java/org/apache/commons/cli/PatternOptionBuilderTest.java b/src/test/java/org/apache/commons/cli/PatternOptionBuilderTest.java index dd1013eae..a312400fb 100644 --- a/src/test/java/org/apache/commons/cli/PatternOptionBuilderTest.java +++ b/src/test/java/org/apache/commons/cli/PatternOptionBuilderTest.java @@ -32,6 +32,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; +import java.util.Locale; import java.util.Vector; import org.junit.jupiter.api.Test; @@ -118,7 +119,7 @@ void testSimplePattern() throws Exception { */ final Options options = PatternOptionBuilder.parsePattern("a:b@cde>f+n%t/m*z#"); final Date expectedDate = new Date(1023400137000L); - final DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy"); + final DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH); final String[] args = {"-c", "-a", "foo", "-b", "java.util.Vector", "-e", "build.xml", "-f", "java.util.Calendar", "-n", "4.5", "-t", "https://commons.apache.org", "-z", dateFormat.format(expectedDate), "-m", "test*"}; final CommandLineParser parser = new PosixParser(); diff --git a/src/test/java/org/apache/commons/cli/TypeHandlerTest.java b/src/test/java/org/apache/commons/cli/TypeHandlerTest.java index 987450734..0eaf1bf4b 100644 --- a/src/test/java/org/apache/commons/cli/TypeHandlerTest.java +++ b/src/test/java/org/apache/commons/cli/TypeHandlerTest.java @@ -38,6 +38,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.stream.Stream; @@ -93,7 +94,7 @@ private static Stream createValueTestParameters() throws MalformedURL * problem, convert the time into a string and then unparse that using the converter. This produces strings that always match the correct time zone. */ final Date date = new Date(1023400137000L); - final DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy"); + final DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH); list.add(Arguments.of(Instantiable.class.getName(), PatternOptionBuilder.CLASS_VALUE, Instantiable.class)); list.add(Arguments.of("what ever", PatternOptionBuilder.CLASS_VALUE, ParseException.class));