Просто для дополнения ответа YCF_L:
Использование буквы в кавычках в шаблоне, как это было сделано с Z (это внутри кавычек: 'Z'
), неправильно. Это будет рассматривать Z как литерал и игнорировать смещение объекта.
В данном конкретном случае это работает, но «Z» в конце означает, что дата указана в формате UTC, и вы не можете жестко закодировать ее как литерал. Помещение в кавычки всегда будет печатать «Z» независимо от смещения, давая неправильные результаты.
Пример:
// wrong: it uses Z inside quotes
DateTimeFormatter wrong = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss:SSS'Z'");
// correct: it uses the offset pattern (X)
DateTimeFormatter correct = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss:SSSXXX");
// print a date/time not in UTC
String ip2 = "2011-05-01T00:00:00.000-05:00";
ZonedDateTime mzt = ZonedDateTime.parse(ip2);
System.out.println(mzt.format(wrong)); // 2011-05-01T00:00:00:000Z
System.out.println(mzt.format(correct)); // 2011-05-01T00:00:00:000-05:00
Обратите внимание, что неправильный форматер печатает Z, что неверно, поскольку смещение mzt
равно -05:00
.
Неправильный форматер работает для вашего случая , потому что вы используете UTC:
// convert to UTC
ZonedDateTime mzt2 = mzt.withZoneSameInstant(ZoneOffset.UTC);
System.out.println(mzt2.format(wrong)); // 2011-05-01T05:00:00:000Z
System.out.println(mzt2.format(correct)); // 2011-05-01T05:00:00:000Z
В этом случае оба форматера выводят правильный результат, но это совпадение , потому что mzt2
в UTC (поэтому смещение равно "Z"). Но для любого смещения, отличного от UTC, будет работать только правильный форматер.
Также обратите внимание, что я использовал withZoneSameInstant
, который имеет тот же результат, что и .toInstant().atZone(ZoneOffset.UTC)
.