Подтвердить что ты не робот

Использование Joda-Time: DateTime, DateMidnight и LocalDate

Joda-Time библиотека включает в себя различные классы datetime

DateTime - Неизменяемая замена для календаря JDK
DateMidnight- Неизменяемый класс, представляющий дату, когда время вынуждено midnight
LocalDateTime - Неизменяемый класс, представляющий локальный дата и время (без часовой пояс)

Мне интересно, как вы используете эти классы в своих многоуровневых приложениях.

Я вижу преимущества в том, что почти все интерфейсы используют LocalDateTime (хотя бы на уровне сервиса), так что моему приложению не нужно управлять часовыми поясами и можно смело предположить, что Times всегда в UTC. Мое приложение затем может использовать DateTime для управления часовыми поясами в самом начале потока выполнения.

Мне также интересно, в каком сценарии может быть полезно DateMidnight.

4b9b3361

Ответ 1

Я вижу преимущества наличия почти всех Интерфейсы, использующие LocalDateTime (at уровень обслуживания по крайней мере), чтобы мой Приложению не нужно управлять Временные часовые пояса и могут спокойно использовать Times всегда в формате UTC.

Я не уверен, что я понимаю вашу мысль. LocalDateTime и DateTime представляют два совершенно разных понятия. Это не тот случай, когда a LocalDateTime имеет неявный часовой пояс UTC: на самом деле он не имеет часовой пояс (внутри он может быть представлен как DateTime с часовым поясом UTC, но это всего лишь деталь реализации, для программиста это не имеет значения использует его).

В документах API вы можете видеть, что, хотя DateTime является < Instant "(точка в мировой временной линии, физическая концепция), LocalDateTime НЕ ТАКОЕ. LocalDateTime на самом деле Partial (" гражданская "концепция), в другой иерархии классов, Названия классов могут, к сожалению, заставлять вас думать, что LocalDateTime является некоторой специализацией DateTime: ну, это не так.

A LocalDateTime следует рассматривать как пару { Date (Y/M/D); Time (hh:mm:ss.msec)} - куча чисел, которая соответствует "гражданскому" стандарту представления данных, связанных с временем. Если нам дано LocalDateTime, мы не можем преобразовать его непосредственно в DateTime, нам нужно указать часовой пояс; и это преобразование переводит нас в другой вид сущности. (Аналогия: строки и потоки байтов в Java: для преобразования между ними вы должны указать кодировку кодировки, потому что они концептуально разные вещи)

Если использовать одну или другую сторону в приложении... иногда обоснованную, но часто достаточно ясно, когда понятия Jodatime понятны. И ИМО мало чем связано с "слоями", возможно, больше для использования случаев или сценариев.

Нетривиальный пример -порядка: вы работаете в Google, программируя Календарь. Вы должны позволить пользователю управлять (добавлять, видеть, изменять) событие, которое включает дату-дату (позволяет игнорировать повторяющиеся события), например: "У меня есть назначение с моим врачом в 2019-июле-3 в 10:00". Какая сущность времени для использования на программном уровне (для этой утилиты)? Я бы сказал: a LocalDateTime. Поскольку пользователь не имеет дело с физическим моментом времени, но с гражданским временем: дата и время, которое отображает часы в его запястье или в его доме. Он даже не думает о часовых поясах (позволяет игнорировать особый случай пользователя, который путешествует по всему миру...) Затем, на уровне бизнеса и презентации, LocalDateTime кажется правильной сущностью.

Но предположим, что вы также должны кодировать другой сценарий: напоминание. Когда внутренний планировщик Google обнаруживает, что событие, хранящееся пользователем, в будущем будет N минут в будущем, оно должно отправить ему напоминание. Здесь "N минут спустя" является полностью "физической" концепцией времени, поэтому здесь "бизнес-уровень" будет иметь дело с DateTime. Существует несколько альтернатив, например: событие хранилось в БД как LocalDateTime (то есть просто время и дата без часового пояса - для представления этого часто используется временная метка UTC, но это деталь реализации). В этом сценарии (только в этом) мы должны загрузить его как DateTime, мы его преобразуем с использованием часового пояса, возможно, из профиля пользователя.

Ответ 2

Ответ leonbloy является правильным и жизненно важным. Я просто переводю на классы java.time, которые заменяют проект Joda-Time.

java.time

Удельный момент

В определенный момент времени:

  • Всегда в UTC представлен Instant.
  • Назначение смещения-от-UTC представлено OffsetDateTime.
  • Назначить полный часовой пояс, а не просто смещение, представлен ZonedDateTime.

Все они заменяют класс Instant и DateTime в Joda-Time. Эти классы java.time имеют разрешение наносекунды в сравнении с миллисекундами, используемыми Joda-Time.

Полночь против Начала дня

В полночь проект "Йода-время" завершил "полночь" - это неопределенное и непроизводительное понятие. Ночные классы и полуночи были устаревшими в более поздних версиях Joda-Time, замененных практической концепцией "первого момента дня".

Классы java.time взяли тот же урок, используя подход "первый момент дня". Ищите методы atStartOfDay для классов java.time, таких как LocalDate.

Никогда не предполагайте, что день начнется в 00:00. Аномалии, такие как летнее время (DST), означают, что день может начинаться в другое время, например, 01:00.

ZonedDateTime zdt = 
    LocalDate.of( 2017 , Month.MARCH , 12 )                    // Instantiate a date-only value without time zone.
             .atStartOfDay( ZoneId.of( "America/Havana" ) ) ;  // Cuba jumps from 00:00 to 01:00 on Spring DST cut-over.

Например, см., как Куба начинает день в 1 час ночи при их сокращении Spring DST.

zdt: 2017-03-12T01: 00-04: 00 [Америка/Гавана]

незональный

Для представления неопределенного представления о возможных моментах в диапазоне около 26-27 часов, но не фактическом моменте на временной шкале, используйте LocalDateTime. Этот класс специально не имеет никакого смещения-от-UTC или часового пояса.

LocalDateTime ldt = LocalDateTime.of( 2017 , Month.JANUARY , 23 , 1 , 2 , 3 , 0 ) ;

Если ваш бизнес-контекст подразумевает определенный часовой пояс, вы можете применить его для получения ZonedDateTime.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;  // Determine a specific point on timeline by providing the context of a time zone.

О java.time

Структура java.time встроена в Java 8 и более поздних версий. Эти классы вытесняют неприятные старые legacy классы времени, такие как java.util.Date, Calendar и SimpleDateFormat.

Проект Joda-Time, теперь режим обслуживания, советуем перейти к классам java.time.

Чтобы узнать больше, см. Учебник Oracle. И поиск Qaru для многих примеров и объяснений. Спецификация JSR 310.

Где получить классы java.time?

  • Java SE 8, Java SE 9, а затем
    • Встроенный.
    • Часть стандартного Java API с объединенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональных возможностей java.time портирована на Java 6 и 7 в ThreeTen-Backport.
  • Android

Проект ThreeTen-Extra расширяет java.time с помощью дополнительных классов. Этот проект является доказательством возможных будущих дополнений к java.time. Здесь вы можете найти полезные классы, такие как Interval, YearWeek, YearQuarter и больше.