#java #date #datetime #timezone-offset #datetimeformatter
#java #Дата #дата и время #смещение часового пояса #datetimeformatter
Вопрос:
Получение a DateTimeParseExcpetion
при попытке преобразовать строку 2020-04-01T08:53:47.000 02:00 00:00
String date = "2020-04-01T08:53:47.000 02:00 00:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSz");
parsedDate = LocalDateTime.parse(date,formatter).toString();
System.out.println(parsedDate);
Комментарии:
1. Что должны означать цифры в этой строке? Похоже, что кто-то добавил дополнительную
00:00
дату и время в формате ISO 8601 со смещением от UTC (2020-04-01T08:53:47.000 02:00
). Я не могу догадаться, почему они это сделали.
Ответ №1:
Ваш шаблон не совпадает с вашей Строкой. Проверьте последнюю часть , где находится 000 02:00 00:00
.
Ваш шаблон таков: SSSz
Если вы попробуете это:
String date = "2020-04-01T08:53:47.000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
Это сработает, потому что ваша дата похожа на ваш шаблон. Обратите внимание, что каждое число в дате тоже входит в шаблон.
Но для вашей даты есть пустое место, что не имеет смысла, поэтому, удалив его, код работает отлично.
String date = "2020-04-01T08:53:47.000 02:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSz");
Вывод:
2020-04-01T08:53:47
Обратите внимание, что z
это местное время и означает «смещение на нулевой час» или «время зулу» (UTC), и вы можете использовать Locale
.
Ответ №2:
Строка 00:00
в конце вашей строки даты и времени для меня не имеет смысла. Проанализируйте строку даты и времени после ее удаления.
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDate = "2020-04-01T08:53:47.000 02:00 00:00";
strDate = strDate.substring(0, strDate.lastIndexOf(' '));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSz", Locale.ENGLISH);
LocalDateTime parsedDate = LocalDateTime.parse(strDate, formatter);
System.out.println(parsedDate);
OffsetDateTime odt = OffsetDateTime.parse(strDate);
System.out.println(odt);
System.out.println(odt.getOffset());
}
}
Вывод:
2020-04-01T08:53:47
2020-04-01T08:53:47 02:00
02:00
Примечание: вы можете проанализировать вашу строку даты и времени (после чередования 00:00
с конца) OffsetDateTime
, чтобы сохранить информацию о смещении зоны.
Ответ №3:
Используйте встроенный форматировщик
Встроенный DateTimeFormatter.ISO_OFFSET_DATE_TIME
соответствует той части вашей строки, которую мы можем понять. И он может анализировать только эту часть и игнорировать остальное.
String date = "2020-04-01T08:53:47.000 02:00 00:00";
ParsePosition pp = new ParsePosition(0);
OffsetDateTime odt = OffsetDateTime.from(
DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(date, pp));
System.out.println("Date and time: " odt);
System.out.println("Unparsed text: " date.substring(pp.getIndex()));
Вывод:
Date and time: 2020-04-01T08:53:47 02:00 Unparsed text: 00:00
Поскольку ваша строка содержит смещение от UTC, OffsetDateTime
это правильный класс для анализа. Если бы мы использовали LocalDateTIme
, смещение было бы проигнорировано, и мы бы в конечном итоге не знали, при каком смещении время должно было интерпретироваться, то есть мы не могли знать, в какой момент времени это было. С OffsetDateTime
точкой во времени все однозначно. Если вы хотите перевести на время в вашем собственном часовом поясе, преобразуйте в ZonedDateTime
(все еще нет LocalDateTime
).
ZonedDateTime timeInMyTimeZone = odt.atZoneSameInstant(ZoneId.systemDefault());
System.out.println("Date and time: " timeInMyTimeZone);
Пример вывода:
Date and time: 2020-04-01T11:53:47 05:00[Asia/Aqtobe]
Ссылки
Ссылки на документацию:
DateTimeFormatter.ISO_OFFSET_DATE_TIME
.- Два аргумента
DateTimeFormatter.parse(CharSequence, ParsePosition)
, которые я использовал.