В Java 8 добавлен новый API java.time для работы с датами и временем ( JSR 310 ).
У меня есть дата и время в виде строки (например "2014-04-08 12:30"
). Как я могу получить LocalDateTime
экземпляр из данной строки?
После того, как я закончил работу с LocalDateTime
объектом: Как я могу затем преобразовать LocalDateTime
экземпляр обратно в строку в том же формате, как показано выше?
ZonedDateTime
а неLocalDateTime
. Имя нелогично;Local
означает любую местность в целом , а не по времени конкретной зоны. Таким образом,LocalDateTime
объект не привязан к временной шкале. Чтобы иметь смысл, чтобы получить определенный момент на временной шкале, вы должны применить часовой пояс.LocalDateTime
противZonedDateTime
противOffsetDateTime
противInstant
противLocalDate
противLocalTime
, как сохранить спокойствие о том, почему это так сложно и как сделать это правильно с первого выстрела.LocalDateTime
вероятно, назвали быZonelessOffsetlessDateTime
.Ответы:
Разбор даты и времени
Для создания
LocalDateTime
объекта из строки вы можете использовать статическийLocalDateTime.parse()
метод. Это принимает строку иDateTimeFormatter
как параметр.DateTimeFormatter
Используется для указания шаблона даты / времени.Форматирование даты и времени
Для создания отформатированной строки
LocalDateTime
объекта вы можете использоватьformat()
метод.Обратите внимание, что есть некоторые часто используемые форматы даты / времени, предопределенные как константы в
DateTimeFormatter
. Например: использованиеDateTimeFormatter.ISO_DATE_TIME
для форматированияLocalDateTime
экземпляра сверху приведет к строке"1986-04-08T12:30:00"
.В
parse()
иformat()
методы доступны для всех дата / время , связанные с объектами (например ,LocalDate
илиZonedDateTime
)источник
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX")
format()
класс LocalDateTime, а не экземпляр? По крайней мере, это то, что я сделал: я путатьDateTime
сdateTime
в приведенном выше примере.Вы также можете использовать
LocalDate.parse()
илиLocalDateTime.parse()
наString
без предоставления его с рисунком, еслиString
в формате ISO-8601 .например,
Выход ,
и используйте,
DateTimeFormatter
только если вам приходится иметь дело с другими шаблонами дат.Например, в следующем примере dd MMM uuuu представляет день месяца (две цифры), три буквы названия месяца (январь, февраль, мар, ...) и год из четырех цифр:
Вывод
также помните, что
DateTimeFormatter
объект является двунаправленным; он может анализировать как ввод, так и формат вывода.Вывод
(см. полный список шаблонов для форматирования и анализа DateFormatter )
источник
2018-08-09 12:00:08
но когда я анализирую, я вижуT
добавление, которое мне не нужно. Есть ли способ сделать это?yyyy-MM-dd hh:mm:ss
для разбора и форматирования. Символ T всегда будет отображаться в формате по умолчанию (ISO-8061), но вы можете использовать свои собственные шаблоны.Оба ответа выше очень хорошо объясняют вопрос о строковых шаблонах. Однако на тот случай, если вы работаете с ISO 8601, применять его не нужно,
DateTimeFormatter
поскольку LocalDateTime уже подготовлен к нему:Преобразовать LocalDateTime в строку часового пояса ISO8601
Преобразовать из строки ISO8601 обратно в LocalDateTime
источник
Разбор строки с датой и временем в определенный момент времени (Java называет это "
Instant
") довольно сложен. Java занималась этим в несколько итераций. Последнийjava.time
иjava.time.chrono
охватывает почти все потребности (кроме Time Dilation :)).Однако эта сложность приносит много путаницы.
Ключ к пониманию разбора даты:
Почему у Java так много способов разобрать дату
... и почему
LocalDateTime
,ZonedDateTime
и соавт. так сложноЕсть часовые пояса . Часовой пояс - это, по сути, «полоса» * [1] земной поверхности, власти которой следуют тем же правилам, когда у нее есть смещение времени. Это включает в себя правила летнего времени.
Часовые пояса меняются со временем для разных областей, в основном в зависимости от того, кто кого побеждает. И правила одного часового пояса меняются со временем .
Есть смещения времени. Это не то же самое, что часовые пояса, потому что часовой пояс может быть, например, "Прага", но он имеет смещение летнего времени и зимнего времени.
Если вы получаете временную метку с часовым поясом, смещение может варьироваться в зависимости от того, в какой части года оно находится. В високосный час временная метка может означать 2 разных времени, поэтому без дополнительной информации она не может быть надежной конвертируется.
Примечание. Под меткой времени я подразумеваю «строку, которая содержит дату и / или время, необязательно с часовым поясом и / или смещением времени».
Несколько часовых поясов могут иметь одинаковое временное смещение для определенных периодов. Например, часовой пояс GMT / UTC совпадает с часовым поясом "Лондон", когда смещение летнего времени не действует.
Чтобы сделать это немного сложнее (но это не слишком важно для вашего случая использования):
2040-12-31 24:00:00
может быть допустимая дата и время.) Для этого необходимы регулярные обновления метаданных, которые системы используют для правильного преобразования даты. Например, в Linux вы регулярно получаете обновления пакетов Java, включая эти новые данные.Обновления не всегда сохраняют прежнее поведение для исторических и будущих временных меток. Таким образом, может случиться, что анализ двух временных меток вокруг изменения некоторого часового пояса, сравнивая их, может дать разные результаты при работе на разных версиях программного обеспечения. Это также относится к сравнению между соответствующим часовым поясом и другим часовым поясом.
Если это вызывает ошибку в вашем программном обеспечении, рассмотрите возможность использования какой-либо временной метки, которая не имеет таких сложных правил, как временная метка UNIX .
Из-за 7, для будущих дат, мы не можем точно конвертировать даты. Так, например, текущий синтаксический анализ
8524-02-17 12:00:00
может быть отключен через пару секунд от будущего синтаксического анализа.API JDK для этого развивались с учетом современных потребностей
java.util.Date
немного наивный подход, предполагавший, что есть только год, месяц, день и время. Этого быстро не хватило.java.sql.Date
было введено, со своими собственными ограничениями.Calendar
API был представлен.Как бороться с этим в Java
java.time
Определите, какой тип для анализа метки времени
Когда вы используете строку временной метки, вам нужно знать, какую информацию она содержит. Это решающий момент. Если вы не понимаете это правильно, вы получите загадочные исключения, такие как «Не удается создать мгновенный» или «Отсутствует смещение зоны» или «Неизвестный идентификатор зоны» и т. Д.
Содержит ли она дату и время?
У него есть смещение по времени?
Смещение по времени является
+hh:mm
частью. Иногда+00:00
его можно заменитьZ
на «время зулусов»,UTC
как всемирное координированное время илиGMT
как среднее время по Гринвичу. Они также устанавливают часовой пояс.Для этих временных отметок вы используете
OffsetDateTime
.У него есть часовой пояс?
Для этих временных отметок вы используете
ZonedDateTime
.Зона указана либо
Список часовых поясов составлен «базой данных TZ» при поддержке ICAAN.
Согласно
ZoneId
'javadoc', идентификаторы зоны также могут быть как-то указаны какZ
и смещение. Я не уверен, как это отображается в реальных зонах. Если временная метка, которая имеет только TZ, попадает в високосный час изменения временного смещения, то она неоднозначна, и интерпретация является предметомResolverStyle
, см. Ниже.Если он не имеет ни того , ни другого , то пропущенный контекст принимается или игнорируется. И потребитель должен решить. Поэтому его необходимо проанализировать
LocalDateTime
и преобразоватьOffsetDateTime
, добавив недостающую информацию:Duration
), Или когда вы не знаете, и это не имеет большого значения (например, расписание местного автобуса).Частичная информация о времени
LocalDate
,LocalTime
,OffsetTime
,MonthDay
,Year
, илиYearMonth
из него.Если у вас есть полная информация, вы можете получить
java.time.Instant
. Это также внутренне используется для преобразования междуOffsetDateTime
иZonedDateTime
.Выяснить, как разобрать это
Существует обширная документация,
DateTimeFormatter
которая может анализировать строку метки времени и форматировать строку.В заранее созданных
DateTimeFormatter
s должны охватывать большеменьше все стандартные форматы временных меток. Например,ISO_INSTANT
может разобрать2011-12-03T10:15:30.123457Z
.Если у вас есть какой-то специальный формат, вы можете создать свой собственный DateTimeFormatter (который также является синтаксическим анализатором).
Я рекомендую взглянуть на исходный код
DateTimeFormatter
и узнать, как его создатьDateTimeFormatterBuilder
. Пока вы там, также посмотрите,ResolverStyle
какие элементы управления имеют формат LENIENT, SMART или STRICT для форматов и неоднозначной информации.TemporalAccessor
Теперь частая ошибка состоит в том, чтобы пойти в сложность
TemporalAccessor
. Это происходит от того, как разработчики привыкли работать сSimpleDateFormatter.parse(String)
. Хорошо,DateTimeFormatter.parse("...")
дает вамTemporalAccessor
.Но, обладая знаниями из предыдущего раздела, вы можете легко разобрать нужный вам тип:
Вам на самом деле не нужно
DateTimeFormatter
ни того, ни другого. Типы, которые вы хотите проанализировать, имеютparse(String)
методы.Что касается этого
TemporalAccessor
, вы можете использовать его, если у вас есть смутное представление о том, какая информация содержится в строке, и вы хотите решить во время выполнения.Я надеюсь, что пролил немного света понимания на вашу душу :)
Примечание: есть обратный порт
java.time
для Java 6 и 7: ThreeTen-Backport . Для Android у него есть ThreeTenABP .[1] Мало того, что они не полосатые, но также есть некоторые странные крайности. Например, некоторые соседние тихоокеанские острова имеют часовые пояса +14: 00 и -11: 00. Это означает, что в то время как на одном острове есть 1 мая 3 часа дня, на другом острове не так уж и далеко, еще 30 апреля 12 часов вечера (если я правильно посчитал :))
источник
ПОЛУЧИТЕ ТЕКУЩЕЕ ВРЕМЯ UTC В ТРЕБУЕМОМ ФОРМАТЕ
источник
Я нашел замечательным охватить несколько вариантов формата даты и времени, например:
источник