Joda-Time: использование DateTime, DateMidnight и LocalDate - PullRequest
31 голосов
/ 29 марта 2010

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

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

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

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

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

Ответы [ 2 ]

77 голосов
/ 17 апреля 2010

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

Я не уверен, что понимаю ваше мышление здесь. LocalDateTime и DateTime представляют два совершенно разных понятия. Это не тот случай, когда 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: для преобразования между ними необходимо указать кодировку charset, потому что это концептуально разные вещи)

Когда использовать один или другой в приложении ... это иногда спорно, но часто достаточно ясно, когда понятия Jodatime понятны. И ИМО не имеет большого отношения к «слоям», возможно, больше к случаям использования или сценариям.

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

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

0 голосов
/ 31 декабря 2017

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

java.time

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

Для определенного момента на временной шкале:

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

Все они заменяют класс Instant & DateTime в Joda-Time. Все эти классы java.time имеют разрешение наносекунд по сравнению с миллисекундами, используемыми Joda-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:00 на своем весеннем переходе на летнее время.

дата: 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 и более поздние версии. Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat. Проект Joda-Time , находящийся сейчас в режиме обслуживания , рекомендует перейти на классы java.time . Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация 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 Проект ThreeTenABP адаптируется ThreeTen-Backport (упомянутый выше) специально для Android. См. Как использовать ThreeTenABP… . Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval, YearWeek, YearQuarter и more .

...