Я не говорю, что это хорошее решение, но кажется, что оно проходит.
Map<Long, String> dayOfWeekTexts = Map.of(1L, "Mo", 2L, "Di",
3L, "Mi", 4L, "Do", 5L, "Fr", 6L, "Sa", 7L, "So");
Map<Long, String> monthTexts = Map.ofEntries(Map.entry(1L, "Jan"),
Map.entry(2L, "Feb"), Map.entry(3L, "Mär"), Map.entry(4L, "Apr"),
Map.entry(5L, "Mai"), Map.entry(6L, "Jun"), Map.entry(7L, "Jul"),
Map.entry(8L, "Aug"), Map.entry(9L, "Sep"), Map.entry(10L, "Okt"),
Map.entry(11L, "Nov"), Map.entry(12L, "Dez"));
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendText(ChronoField.DAY_OF_WEEK, dayOfWeekTexts)
.appendLiteral(' ')
.appendText(ChronoField.MONTH_OF_YEAR, monthTexts)
.appendPattern(" dd HH:mm:ss z Z yyyy")
.toFormatter(Locale.GERMANY);
String toParse = "Mo Aug 18 11:25:26 MESZ +0200 2014";
OffsetDateTime odt = OffsetDateTime.parse(toParse, formatter);
System.out.println(odt);
ZonedDateTime zdt = ZonedDateTime.parse(toParse, formatter);
System.out.println(zdt);
Вывод работает на моем Oracle JDK 10.0.1:
2014-08-18T11:25:26+02:00
2014-08-18T11:25:26+02:00[Europe/Berlin]
С другой стороны, никакого хорошего решения не может быть.
java.time
, современный Java-интерфейс даты и времени, позволяет нам указывать тексты, используемые для полей как для форматирования, так и для синтаксического анализа.Поэтому я использую это как для дня недели, так и для месяца, указывая сокращения без точки, которые использовались со старыми данными языкового стандарта COMPAT или JRE.Я использовал Java 9 Map.of
и Map.ofEntries
для построения карт, которые нам нужны.Если это также работает в Java 8, вы должны найти какой-то другой способ заполнить две карты, я вам верю.
Если вам нужен старомодный java.util.Date
(вероятно, вустаревшая кодовая база), конвертируйте так:
Date date = Date.from(odt.toInstant());
System.out.println("As legacy Date: " + date);
Вывод в моем часовом поясе (Европа / Копенгаген, вероятно, примерно соответствует вашему):
As legacy Date: Mon Aug 18 11:25:26 CEST 2014
Предложение по стратегии
Я думаю, что если бы это был я, я бы поступил следующим образом:
- Подождите .Установите соответствующее системное свойство из Java:
System.setProperty("java.locale.providers", "COMPAT,CLDR");
, чтобы оно не было забыто ни в одной среде.Данные локали COMPAT существуют примерно с 1.0 (я думаю, по крайней мере, близко), поэтому от них зависит много кода (не только вашего).Название было изменено с JRE на COMPAT в Java 9. Для меня это может звучать как план сохранить данные в течение достаточно долгого времени.Согласно документации по раннему доступу она все еще будет доступна в Java 11 (следующая версия Java "долгосрочной поддержки") без предупреждения об устаревании или чего-либо подобного.И если он будет удален в какой-то будущей версии Java, вы, вероятно, сможете вскоре выяснить, что можете решить проблему до обновления. - Используйте мое решение выше .
- Используйте интерфейс поставщика услуг локали , с которым связан Василий Бурк.Нет сомнений, что это хорошее решение на случай, если данные COMPAT будут удалены в неизвестное время в будущем.Возможно, вы даже сможете скопировать данные локали COMPAT в ваши собственные файлы, чтобы они не могли их отобрать у вас, а только проверьте, есть ли проблемы с авторским правом, прежде чем вы это сделаете.Причина, по которой я в последний раз упоминаю о хорошем решении, заключается в том, что вы сказали, что не довольны необходимостью устанавливать системное свойство в любой возможной среде, в которой может выполняться ваша программа.Насколько я могу судить, использование ваших собственных данных локали через интерфейс поставщика услуг локали все равно потребует от вас установки того же системного свойства (только для другого значения).