Следующий UnitTest дает сбой при выполнении через IntelliJ IDE на компьютере с Windows (Java 11.0.9), но проходит успешно при выполнении на компьютере Mac или Linux с той же версией Java.
@Test
public void rfc1123JaveTimeUtilParsing(){
final String rfc1123Pattern = "EEE, dd MMM yyyy HH:mm:ss z";
final String responseTimeStamp = "Mon, 14 Dec 2020 20:34:37 GMT";
DateTimeFormatter javaTimeDateTimeFormatter = DateTimeFormatter.ofPattern(rfc1123Pattern);
ZonedDateTime javaFinalTime = ZonedDateTime.parse(responseTimeStamp, javaTimeDateTimeFormatter);
Assert.assertNotNull(javaFinalTime);
}
Для окон результатом является следующее исключение:
java.time.format.DateTimeParseException: текст «Пн, 14 декабря 2020 г., 20:34:37 по Гринвичу» не может быть проанализирован по индексу 0
Добавление к комментарию @YCF_L DateTimeFormatter.ofPattern(String) использует «локаль FORMAT по умолчанию». который основан на том, который вы указали в своей ОС, поэтому, если ваш компьютер с Windows и ваш компьютер с Mac или Linux имеют разные локали, форматер будет давать разные результаты.
@YCF_L — для тестов в большинстве случаев Locale.ROOT
будет лучшим выбором, если только вы не тестируете вещи, специфичные для конкретной локали. Но Locale.UK
было бы хорошей отправной точкой для этого вопроса…
Спасибо, ребята, за ответы. Locale.ENGLISH решил проблему.
DateTimeFormatter
без Locale
.Поскольку данная дата и время указаны на английском языке, вы должны использовать DateTimeFormatter
с Locale.ENGLISH
.
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
final String responseTimeStamp = "Mon, 14 Dec 2020 20:34:37 GMT";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(responseTimeStamp, dtf);
System.out.println(zdt);
}
}
Выход:
2020-12-14T20:34:37Z[GMT]
По умолчанию DateTimeFormatter#ofPattern использует локаль FORMAT по умолчанию, которую JVM устанавливает во время запуска в зависимости от среды хоста. Я попытался проиллюстрировать проблему с помощью следующей демонстрации:
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
final String responseTimeStamp = "Mon, 14 Dec 2020 20:34:37 GMT";
DateTimeFormatter dtfWithDefaultLocale = null;
System.out.println("JVM's Locale: " + Locale.getDefault());
// DateTimeFormatter with the default Locale
dtfWithDefaultLocale = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss z");
System.out.println("DateTimeFormatter's Locale: " + dtfWithDefaultLocale.getLocale());
System.out.println(
"Parsed with JVM's default locale: " + ZonedDateTime.parse(responseTimeStamp, dtfWithDefaultLocale));
// DateTimeFormatter with Locale.ENGLISH explicitly (recommended)
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(responseTimeStamp, dtf);
System.out.println("Parsed with Locale.ENGLISH: " + zdt);
// Setting the JVM's default locale to Locale.FRANCE
Locale.setDefault(Locale.FRANCE);
System.out.println("JVM's Locale: " + Locale.getDefault());
// DateTimeFormatter with the default Locale
dtfWithDefaultLocale = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss z");
System.out.println("DateTimeFormatter's Locale: " + dtfWithDefaultLocale.getLocale());
System.out.println(
"Parsed with JVM's default locale: " + ZonedDateTime.parse(responseTimeStamp, dtfWithDefaultLocale));
}
}
Выход:
JVM's Locale: en_GB
DateTimeFormatter's Locale: en_GB
Parsed with JVM's default locale: 2020-12-14T20:34:37Z[GMT]
Parsed with Locale.ENGLISH: 2020-12-14T20:34:37Z[GMT]
JVM's Locale: fr_FR
DateTimeFormatter's Locale: fr_FR
Exception in thread "main" java.time.format.DateTimeParseException: Text 'Mon, 14 Dec 2020 20:34:37 GMT' could not be parsed at index 0
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
at java.base/java.time.ZonedDateTime.parse(ZonedDateTime.java:598)
at Main.main(Main.java:29)
Большое спасибо за очень подробное объяснение и примеры. Я включил Locale в свой тест, и это решило проблему. Я из Аргентины, и служба находится в США. Так что использования Locale.ENGLISH было достаточно.
попробуйте указать Locale:
DateTimeFormatter.ofPattern(rfc1123Pattern, Locale.UK)