Преобразование строковой даты 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);.
Ответы
Ваш формат неверен. Вы использовали 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), это наблюдение не поможет нам в вашем случае.
Ссылка
- Статья в Википедии: ISO 8601