Разобрать строку до даты определенного формата
У меня есть строка следующего формата
String stringDate = "2019-04-25T07:03:17.428Z";
и мне нужно преобразовать его в объект LocalDateTime формата 2019-04-2507:03:17
Я пробовал с
LocalDateTime.parse(stringDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
но я получаю это исключение синтаксического анализа:
Exception in thread "main" java.time.format.DateTimeParseException: Text '2019-04-25T07:03:17.428Z' could not be parsed at index 10
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:492)
at com.company.Main.main(Main.java:12)
Каким будет способ конвертировать в конкретный формат?
3 ответа
Что вы просили (но не хотите)
String stringDate = "2019-04-25T07:03:17.428Z";
LocalDateTime ldt = LocalDateTime.parse(stringDate, DateTimeFormatter.ISO_OFFSET_DATE_TIME)
.truncatedTo(ChronoUnit.SECONDS);
System.out.println(ldt);
Выход
2019-04-25T07:03:17
Он дает вам то, что вы сказали, что хотели, но, как указывает rzwitserloot в другом ответе , это не имеет смысла. Он игнорирует смещение
Z
это было в твоей строке. Смещение имеет решающее значение для интерпретации даты и времени как момента времени. Если бы строка была
2019-04-25T07:03:17.428+13:00
вместо этого вы все равно получите тот же результат, даже если строка обозначает момент времени на 13 часов раньше.
Призыв к
truncatedTo()
избавляется от доли секунды. Если вы можете жить с этой долей секунды, опустите этот призыв.
Что вы можете захотеть вместо этого
Для более разумного преобразования:
ZoneId zone = ZoneId.of("Europe/Zagreb");
Instant pointInTime = Instant.parse(stringDate);
LocalDateTime ldt = pointInTime.atZone(zone)
.toLocalDateTime()
.truncatedTo(ChronoUnit.SECONDS);
System.out.format("Date and time in %s: %s%n", zone, ldt);
Дата и время в Европе / Загребе: 2019-04-25T09:03:17
Теперь время 07:03 UTC было преобразовано в 09:03 Центральноевропейского летнего времени.
Изменить: если вам действительно нужен
LocalDateTime
в UTC, например, для столбца базы данных, требующего этого, вы можете сделать этот факт явным в своем коде следующим образом:
LocalDateTime ldt = pointInTime.atOffset(ZoneOffset.UTC)
.toLocalDateTime()
.truncatedTo(ChronoUnit.SECONDS);
System.out.format("Date and time in UTC: %s%n", ldt);
Дата и время в UTC: 2019-04-25T07: 03: 17
Что пошло не так в вашем коде?
Чтобы понять, что для вас не удалось, давайте посмотрим на полученное вами сообщение об исключении:
Текст '2019-04-25T07: 03: 17.428Z' не удалось проанализировать в индексе 10
Индекс 10 - это то место, где находится начало временной части. Давайте сравним с вашей строкой шаблона формата:
yyyy-MM-dd HH:mm:ss
. Перед временной частью стоит пробел. Это было причиной исключения. Если вам нужно было указать в шаблоне, что
T
должен быть там, нам нужно будет заключить его в одинарные кавычки, например
yyyy-MM-dd'T'HH:mm:ss
.
Ваш вклад, по сути, не является LDT. Это ZDT - Z - это зона (ZonedDateTime). Таким образом, невозможно преобразовать эту строку напрямую в LDT, и это хорошо, потому что это не имеет смысла.
Преобразуйте его в ZDT. Затем преобразуйте это в LDT. Это вызов одного метода.
Вы можете сначала проанализировать его с помощью java.time.Instant, а затем использовать метод ofInstant из примера java.time.LocalDateTime :
String stringDate = "2019-04-25T07:03:17.428Z";
var instant = Instant.parse(stringDate);
var localDateTime = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);