Я знаю это:
- Instant - это скорее «техническое» представление меток времени (наносекунды) для вычислений.
- LocalDateTime - это скорее представление даты / часов, включая часовые пояса для людей.
Тем не менее, в конце концов, IMO можно использовать как тип для большинства случаев применения. Как пример: в настоящее время я выполняю пакетное задание, в котором мне нужно рассчитать следующий прогон на основе дат, и я изо всех сил пытаюсь найти плюсы / минусы между этими двумя типами (кроме преимущества точности в наносекундах в Instant и части часового пояса). LocalDateTime).
Можете ли вы назвать примеры приложений, в которых следует использовать только Instant или LocalDateTime?
Изменить: Остерегайтесь неверно прочитанных документов для LocalDateTime относительно точности и часового пояса
LocalDateTime
это не имеет часовой пояс!Ответы:
ТЛ; др
Instant
иLocalDateTime
два совершенно разных животных: одно представляет момент, другое нет.Instant
представляет момент, конкретную точку на временной шкале.LocalDateTime
представляет дату и время суток. Но без часового пояса или смещения от UTC этот класс не может представлять момент . Он представляет потенциальные моменты в диапазоне от 26 до 27 часов, диапазон всех часовых поясов по всему земному шару.Неверная презумпция
Ваше утверждение неверно: A
LocalDateTime
не имеет часового пояса . Отсутствие часового пояса - весь смысл этого класса.Процитируем документ этого класса:
Так
Local…
значит «не зонировано, нет смещения».Instant
Это
Instant
момент на временной шкале в UTC , подсчет наносекунд со времени первого момента 1970 UTC (в основном, см. Подробности в документе doc). Поскольку большая часть вашей бизнес-логики, хранилища данных и обмена данными должна быть в формате UTC, этот класс удобно использовать часто.OffsetDateTime
Класс
OffsetDateTime
class представляет момент в виде даты и времени с контекстом, состоящим из некоторого количества часов, минут и секунд перед или после UTC. Количество смещения, количество часов-минут-секунд, представленоZoneOffset
классом.Если число часов-минут-секунд равно нулю,
OffsetDateTime
то момент времени в UTC представляет собой то же самое, что и момент времениInstant
.ZoneOffset
ZoneOffset
Класс представляет собой смещение от-UTC- , количество часов-минут-секунд впереди UTC или позади UTC.А
ZoneOffset
это просто количество часов-минут-секунд, не более того. Зона намного больше, имеет имя и историю изменений для смещения. Поэтому использование зоны всегда предпочтительнее, чем простое смещение.ZoneId
Временная зона представлена
ZoneId
классом.Например, в Париже новый день наступает раньше, чем в Монреале . Поэтому нам нужно передвинуть стрелки часов, чтобы лучше отразить полдень (когда Солнце находится прямо над головой) для данного региона. Чем дальше на восток / запад от линии UTC в Западной Европе / Африке, тем больше смещение.
Часовой пояс - это набор правил для обработки корректировок и аномалий, практикуемых местным сообществом или регионом. Самая распространенная аномалия - это слишком популярное безумие, известное как летнее время .
Часовой пояс имеет историю прошлых правил, настоящих правил и правил, подтвержденных на ближайшее будущее.
Эти правила меняются чаще, чем вы могли ожидать. Обязательно обновляйте правила библиотеки даты и времени, обычно копии базы данных 'tz' . Поддерживать актуальность теперь проще, чем когда-либо, в Java 8, когда Oracle выпустила средство обновления часовых поясов .
Укажите правильное время имя зоны в формате
Continent/Region
, напримерAmerica/Montreal
,Africa/Casablanca
илиPacific/Auckland
. Никогда не используйте 2-4-буквенное сокращение, такое какEST
илиIST
поскольку они не являются истинными часовыми поясами, не стандартизированы и даже не уникальны (!).ZonedDateTime
Думайте
ZonedDateTime
концептуально какInstant
с назначеннымZoneId
.Чтобы запечатлеть текущий момент, как видно на часах настенных часов, используемых людьми определенного региона (часового пояса):
Почти все ваши бэкэнд, база данных, бизнес-логика, постоянство данных, обмен данными должны быть в UTC. Но для представления пользователям необходимо настроить часовой пояс, ожидаемый пользователем. Это цель
ZonedDateTime
класса и классов форматирования, используемых для генерации строковых представлений этих значений даты и времени.Вы можете генерировать текст в локализованном формате, используя
DateTimeFormatter
.LocalDate
,LocalTime
,LocalDateTime
«Местный» классы дат и времени,
LocalDateTime
,LocalDate
,LocalTime
, являются различного рода зверька. Они не привязаны ни к одной местности или часовому поясу. Они не привязаны к временной шкале. Они не имеют никакого реального смысла, пока вы не примените их к местности, чтобы найти точку на временной шкале.Слово «Локальный» в этих именах классов может быть нелогичным для непосвященных. Слово означает любую местность или каждую местность, но не конкретную местность.
Поэтому для бизнес-приложений «локальные» типы используются не часто, поскольку они представляют только общее представление о возможной дате или времени, а не о конкретном моменте на временной шкале. Бизнес-приложения, как правило, заботятся о точном моменте поступления счета-фактуры, о товаре, отправленном для перевозки, о найме сотрудника или о выходе такси из гаража. Так что разработчики бизнес-приложений используют
Instant
иZonedDateTime
классы чаще всего.Так, когда мы будем использовать
LocalDateTime
? В трех ситуациях: когда мы хотим применить определенную дату и время дня в нескольких местах, где мы бронируем встречи или когда у нас есть предполагаемый, но еще не определенный часовой пояс. Обратите внимание, что ни один из этих трех случаев не является одной определенной конкретной точкой на временной шкале, ни один из них не является моментом.Одно время дня, несколько моментов
Иногда мы хотим представлять определенное время суток на определенную дату, но хотим применить его к нескольким местам в разных часовых поясах.
Например, «Рождество начинается в полночь 25 декабря 2015 года»
LocalDateTime
. Полночь бьет в разные моменты в Париже, чем в Монреале, и снова в Сиэтле и в Окленде .Другой пример: «У компании Acme есть политика, согласно которой обеденный перерыв начинается в 12:30 на каждом из ее заводов по всему миру»
LocalTime
. Чтобы иметь реальное значение, вам нужно применить его к временной шкале, чтобы определить момент 12:30 на фабрике в Штутгарте или 12:30 на фабрике в Рабате или 12:30 на фабрике в Сиднее .Бронирование назначений
Другая ситуация, которую следует использовать,
LocalDateTime
- это бронирование будущих мероприятий (например, приемы у стоматолога). Эти назначения могут быть достаточно далеко в будущем, что вы рискуете политиков переопределить часовой пояс. Политики часто предупреждают или даже не предупреждают вообще. Если вы имеете в виду «3 часа дня следующего января 23-го» независимо от того, как политики могут играть с часами, то вы не можете записать момент - это будет означать, что 3 часа дня превратятся в 14 или 16 часов, если в этом регионе будет принят или отменен переход на летнее время, например.Для встреч храните А
LocalDateTime
и АZoneId
, хранятся отдельно. Позже, при создании расписания, на лету определяют момент, вызываяLocalDateTime::atZone( ZoneId )
для созданияZonedDateTime
объекта.При необходимости вы можете настроить на UTC. Извлечь
Instant
изZonedDateTime
.Неизвестная зона
Некоторые люди могут использовать
LocalDateTime
в ситуации, когда часовой пояс или смещение неизвестны.Я считаю этот случай неуместным и неразумным. Если зона или смещение предназначены, но не определены, у вас неверные данные. Это все равно что хранить цену товара, не зная предполагаемой валюты. Не хорошая идея.
Все типы даты и времени
Для полноты приведем таблицу всех возможных типов даты и времени, как современных, так и устаревших в Java, а также типов, определенных стандартом SQL. Это может помочь поместить классы
Instant
&LocalDateTime
в более широкий контекст.Обратите внимание на странный выбор, сделанный командой Java при разработке JDBC 4.2. Они решили поддерживать все времена java.time … за исключением двух наиболее часто используемых классов:
Instant
&ZonedDateTime
.Но не волнуйтесь. Мы можем легко конвертировать туда и обратно.
Конвертация
Instant
.Конвертация
ZonedDateTime
.О java.time
Java.time каркас встроен в Java 8 и более поздних версий. Эти классы вытеснять неприятные старые устаревшие классы даты и времени , такие как
java.util.Date
,Calendar
, иSimpleDateFormat
.Проект Joda-Time , находящийся сейчас в режиме обслуживания , рекомендует перейти на классы java.time .
Чтобы узнать больше, смотрите Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии . Нет необходимости в строках, нет необходимости в
java.sql.*
классах.Где взять классы java.time?
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь , такие как
Interval
,YearWeek
,YearQuarter
, и более .источник
Local
именования. Моя интуицияLocal
означает средства относительно того, где я нахожусь и когда я нахожусь (?!), И это заставляет меня поверить, что это действительно то, чтоZonedDateTime
есть.DateTime
класса, используемому его предшественником Joda-Time (производящийZonedDateTime
), чтобы подчеркнуть отличие от «локальных» классов. Думайте о названии «Локальный» как о сокращении «нужно применять к определенной местности».Local
возможно, также был способом отличить пакет java.util, хотя я чувствую, что мог бы быть лучший выбор слова.Одним из основных отличий является
Local
частьLocalDateTime
. Если вы живете в Германии и создаетеLocalDateTime
экземпляр, а кто-то еще живет в США и в тот же момент создает другой экземпляр (при условии, что часы установлены правильно) - значение этих объектов на самом деле будет другим. Это не относится к томуInstant
, что рассчитывается независимо от часового пояса.LocalDateTime
сохраняет дату и время без часового пояса, но его начальное значение зависит от часового пояса.Instant
это не так.Кроме того,
LocalDateTime
предоставляет методы для манипулирования такими компонентами даты, как дни, часы, месяцы. АнInstant
нет.Оба класса имеют одинаковую точность.
LocalDateTime
не хранит часовой пояс. Внимательно читайте javadocs, потому что вы можете совершить большую ошибку с такими неверными предположениями: Instant и LocalDateTime .источник
LocalDateTime stores date and time without timezone, but it's initial value is timezone dependent
? что такое начальное значение и как оно зависит от часового пояса? Спасибо.Вы ошибаетесь
LocalDateTime
: он не хранит информацию о часовом поясе и обладает точностью до наносекунды. Цитирую Javadoc (выделение мое):Разница между ними заключается в том, что она
Instant
представляет собой смещение от эпохи (01-01-1970) и, как таковая, представляет определенный момент на временной шкале. ДваInstant
объекта, созданные в один и тот же момент в двух разных местах Земли, будут иметь абсолютно одинаковое значение.источник
Instant
соответствует времени на простом меридиане (Гринвич).Принимая во внимание, что
LocalDateTime
относительно настроек часового пояса ОС, иисточник