String ip = "2011-05-01T06:47:35.422-05:00";
ZonedDateTime mzt = ZonedDateTime.parse(ip).toInstant().atZone(ZoneOffset.UTC);
System.out.println(mzt);
System.out.println("-----");
String ip2 = "2011-05-01T00:00:00.000-05:00";
ZonedDateTime mzt2 = ZonedDateTime.parse(ip2).toInstant().atZone(ZoneOffset.UTC);
System.out.println(mzt2);
Выход:
2011-05-01T11:47:35.422Z
-----
2011-05-01T05:00Z
Почему в случае 2 меняется формат даты? Из-за этого я получаю ошибку базы данных SQLServer.
Пожалуйста, прочтите документация класса, прежде чем размещать вопрос о таком простом вызове метода.
Это то, что toString из документации сказал
The format used will be the shortest that outputs the full value of the time where the omitted parts are implied to be zero.
Для решения этой проблемы вам понадобится другой форматтер:
String result = mzt2.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss:SSS'Z'"));
Выход
2011-05-01T11:47:35.422Z
2011-05-01T05:00:00:000Z
Ваш ответ дает правильный результат. Но мне нужен объект ZonedDateTime
@SujanDavangereSunil У вас уже есть ZonedDateTime Object
, но вы не можете получить ожидаемый результат, потому что, когда вы попытаетесь распечатать этот объект, он вызовет метод toString
, поэтому этот метод вернет тот результат, которым вы поделились. поделитесь, пожалуйста, дополнительной информацией о вашей проблеме, чтобы мы могли помочь вам ее решить?
Я напечатал здесь System.out, чтобы увидеть результат. Все, что мне нужно, - это объект ZonedDateTimeObject в этом формате, а это случай 1.
ZonedDateTime
не может иметь формат. У него есть только метод toString
, и вы не можете изменить его работу. Если вам нужен конкретный формат, вам необходимо иметь этот формат в String
(а не в ZonedDateTime
). Это также существенное различие: используйте ZonedDateTime
для вашей модели и String
для вашей презентации. Кроме того, зачем вам этот конкретный формат, если ISO 8601 дает свободу, которую берет toString
?
@SujanDavangereSunil прочитал комментарий Оле В.В. пожалуйста, ответьте на ваш предыдущий вопрос
Я хочу, чтобы значение mzt2 было 2011-05-01T05: 00: 00: 000Z. Использование System.out.print будет использовать средство форматирования для печати этого. В моем случае я делаю запись в базе данных, для которой требуется, чтобы значение объекта ZonedDateTime было 2011-05-01T05: 00: 00: 000Z
@SujanDavangereSunil У вас есть XY проблема. Вы думаете, что ваша проблема в том, что toString()
генерирует неправильную строку для вставки в базу данных, тогда как ваша настоящая проблема заключается в том, что вы вообще вызываете toString()
. Не конвертируйте значение даты в строку для вставки в базу данных, вставляйте само значение даты. Если ваш драйвер JDBC не может обрабатывать новые объекты Java Time, вместо этого преобразуйте их в Timestamp
.
Просто чтобы дополнить ответ 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)
.
Кстати, вы используете неправильный класс для своих входных данных и своих манипуляций.
OffsetDateTime
здесь подходит, тогда какZonedDateTime
подходит, когда у вас есть часовой пояс,Continent/Region
, такой какAmerica/Montreal
илиAfrica/Tunis
. А когда вам нужен UTC, просто используйтеInstant
.