Преобразование строковой даты UTC в формат даты
Как преобразовать строку "2020-09-02T12:22:53.9" в формат даты 2020-09-02T12: 22: 53.9 в java?
String dateString = "2020-09-02T12:22:53.9";
String tz = "America/Mexico_City";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-dd-mm hh:mm:ss.S");
ZoneId zoneId = ZoneId.of(tz);
Instant instant = Instant.parse(dateString);
ZonedDateTime dateTimeInTz =ZonedDateTime.ofInstant(instant, zoneId);
System.out.println(dateTimeInTz.format(dtf));
Этот код вызывает
java.time.format.DateTimeParseException: Text '2020-09-02T12:22:53.9' could not be parsed at index 21
сформировать линию
Instant instant = Instant.parse(dateString);
.
2 ответа
Ваш формат неправильный. Вы использовали
mm
, вместо
MM
, за месяц. Кроме того, вы пропустили буквальный
T
в формате. Обратите внимание, что вам нужно использовать
HH
для времени в 24-часовом формате.
Поскольку ваша строка даты и времени не имеет информации о часовом поясе, вам нужно будет проанализировать строку даты и времени, чтобы
LocalDateTime
а затем используйте LocalDateTime#atZone
преобразовать это в
ZonedDateTime
(если вам вообще нужно
ZonedDateTime
) как показано ниже:
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String dateString = "2020-09-02T12:22:53.9";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-dd-MM'T'HH:mm:ss.S");
String tz = "America/Mexico_City";
ZoneId zoneId = ZoneId.of(tz);
// Parse the given date-time string to LocalDateTime
LocalDateTime ldt = LocalDateTime.parse(dateString, dtf);
// Convert the LocalDateTime to ZonedDateTime
ZonedDateTime dateTimeInTz = ldt.atZone(zoneId);
// Display ZonedDateTime in its default format
System.out.println(dateTimeInTz);
// Display ZonedDateTime in your custom format
System.out.println(dateTimeInTz.format(dtf));
}
}
Вывод:
2020-02-09T12:22:53.900-06:00[America/Mexico_City]
2020-09-02T12:22:53.9
В качестве альтернативы вы можете использовать
ZoneId
с участием
DateTimeFormatter
сам, а затем вы можете проанализировать данную строку даты и времени непосредственно в
ZonedDateTime
как показано ниже:
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String dateString = "2020-09-02T12:22:53.9";
String tz = "America/Mexico_City";
ZoneId zoneId = ZoneId.of(tz);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-dd-MM'T'HH:mm:ss.S").withZone(ZoneId.of(tz));
// Parse the given date-time string into ZonedDateTime
ZonedDateTime dateTimeInTz = ZonedDateTime.parse(dateString, dtf);
// Display ZonedDateTime in its default format
System.out.println(dateTimeInTz);
// Display ZonedDateTime in your custom format
System.out.println(dateTimeInTz.format(dtf));
}
}
Вывод:
2020-02-09T12:22:53.900-06:00[America/Mexico_City]
2020-09-02T12:22:53.9
Форматер не нужен
Я полагаю, что ваша строка даты находится в часовом поясе America/Mexico_City и что вы хотите выводить в том же часовом поясе, поэтому те же дата и время. Я также считаю, что внутри вашей программы вы хотите представить момент времени как
Instant
. Полный круг от строки даты до
Instant
и обратно может идти:
String tz = "America/Mexico_City";
ZoneId zoneId = ZoneId.of(tz);
String dateString = "2020-09-02T12:22:53.9";
Instant instant = LocalDateTime.parse(dateString).atZone(zoneId).toInstant();
System.out.println(instant);
ZonedDateTime dateTimeInTz =ZonedDateTime.ofInstant(instant, zoneId);
System.out.println(dateTimeInTz.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
Вывод:
2020-09-02T17:22:53.900Z 2020-09-02T12:22:53.9
Ваш ввод и ваш идентичный вывод находятся в формате ISO 8601.
LocalDateTime
анализирует формат ISO 8601 без часового пояса или смещения по умолчанию, то есть без явного средства форматирования. Для печати
ZonedDateTime
обратно в том же формате, мы используем встроенный
DateTimeFormatter.ISO_LOCAL_DATE_TIME
. Как вы, возможно, уже поняли, отсутствие необходимости указывать нашу собственную строку шаблона формата является большим облегчением.
Что пошло не так в вашем коде?
Арвинд Кумар Авинаш уже сообщил об ошибках в строке шаблона формата. Более того, вы не можете разобрать свою строку в
Instant
или, точнее, для этого нужно нечто большее. Причина в том, что Java и
Instant
класс не знает и не может угадать, какой часовой пояс вы намеревались. В строке даты указаны дата и время без часового пояса. An
Instant
это момент времени, концептуально не имеющий даты или времени суток. Ваша строка может представлять разные моменты времени в разных часовых поясах, поэтому, только указав часовой пояс, можно определить момент времени.
Что за
Instant
класс может анализировать - это дата и время в формате UTC, обозначенные
Z
. Пример такой строки находится на выходе из
Instant
выше,
2020-09-02T17:22:53.900Z
. Поскольку ваша строка не в формате UTC (и, следовательно, не имеет
Z
), это наблюдение не поможет нам в вашем случае.