Поскольку ваша Java 8 работает не так, как следовало бы ожидать, я предлагаю сначала обойти эту проблему, пытаясь разобрать ее без зоны. Если зона или смещение анализируются из строки, это будет использовано. Если синтаксический анализ без зоны не удался, попробуйте с зоной. Для этого используется следующий метод:
private static void parseAndPrint(String formatPattern, String dateTimeString) {
// Try parsing without zone first
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatPattern);
Instant parsedInstant;
try {
parsedInstant = formatter.parse(dateTimeString, Instant::from);
} catch (DateTimeParseException dtpe) {
// Try parsing with zone
ZoneId defaultZone = ZoneId.of("Asia/Calcutta");
formatter = formatter.withZone(defaultZone);
parsedInstant = formatter.parse(dateTimeString, Instant::from);
}
System.out.println("Parsed instant: " + parsedInstant);
}
Давайте попробуем:
parseAndPrint("yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXX", "2018-10-22T02:17:58.717853Z");
parseAndPrint("yyyy-MM-dd'T'HH:mm:ss.SSSSSS", "2018-10-22T02:17:58.717853");
parseAndPrint("EEE MMM d HH:mm:ss zzz yyyy", "Mon Oct 22 02:17:58 CEST 2018");
Вывод на Java 8:
Parsed instant: 2018-10-22T02:17:58.717853Z
Parsed instant: 2018-10-21T20:47:58.717853Z
Parsed instant: 2018-10-22T00:17:58Z
Первый пример имеет смещение в строке и последнее сокращение строки часового пояса в строке, и в обоих случаях они соблюдаются: напечатанный момент скорректировал время в UTC (поскольку Instant
всегда печатается в UTC , его toString
метод гарантирует). Средний пример не имеет ни смещения, ни часового пояса в строке, поэтому используется часовой пояс по умолчанию для Азии / Калькутты, указанный в методе.
Тем не менее, синтаксический анализ трех или четырехбуквенных сокращений часовых поясов, подобных CEST
, является опасной и обескураживающей практикой, поскольку сокращения часто бывают неоднозначными. Я включил пример только для демонстрации.
Есть ли способ использовать один класс ...?
Я использовал Instant
для всех случаев, так что да, есть способ использовать только один класс. Ограничение заключается в том, что впоследствии вы не знаете, был ли в строке какой-либо часовой пояс или смещение, и каким он был. Вы не знали, когда использовали SimpleDateFormat
и Date
, поэтому я решил, что все в порядке?
Ошибка в Java 8?
Результаты вашей демонстрации на тестере REX разочаровывают и ошибочны и не согласуются с результатами, полученными на Java 11. Мне кажется, что вы пострадали от ошибки в Java 8, возможно этот: синтаксический анализ с DateTimeFormatter.withZone не ведет себя, как описано в javadocs .