Различия между Java 8 Date Time API (java.time) и Joda-Time

264

Я знаю, что есть вопросы, касающиеся java.util.Date и Joda-Time. Но после некоторого поиска я не смог найти нить о различиях между API java.time (новинка в Java 8 , определенная JSR 310 ) и Joda-Time .

Я слышал, что java.time API в Java 8 намного чище и может делать гораздо больше, чем Joda-Time. Но я не могу найти примеры, сравнивающие два.

  • Что может сделать java.time, чего не может Joda-Time?
  • Что может java.time сделать лучше, чем Joda-Time?
  • Производительность лучше с java.time?
Zack
источник
8
Это не относится к Java 7, а не к Java 8. Ответ на этот вопрос был отредактирован для Java 8 с очень малой детализацией. Мой вопрос, в частности, касается нового API DateTime в Java 8, а не java.util.Date в Java 7. Я просто ищу ответ, который сравнивает Java 8 с JodaTime.
Zack
2
возможно, этот документ Oracle поможет вам.
MarioDS
Если у вас есть Java 7, используйте дополнительную библиотеку, если у вас есть Java 8, используйте встроенную библиотеку. Поскольку обе библиотеки в основном разработаны одним и тем же человеком, я не уверен, какие основные различия вы ожидаете.
Питер Лори
2
@PeterLawrey: Joda-Time и API даты и времени Java 8 на самом деле сильно отличаются.
jarnbjo
5
Вы также можете прочитать это сообщение в блоге от Стивена Колборна - основного автора обоих проектов.
Мэтт Джонсон-Пинт

Ответы:

416

Общие черты

а) Обе библиотеки используют неизменяемые типы. Joda-Time также предлагает дополнительные изменяемые типы, такие как MutableDateTime.

б) Более того: обе библиотеки вдохновлены исследованием дизайна «TimeAndMoney» Эрика Эванса или идеями Мартина Фаулера о доменно- ориентированном стиле, поэтому они более или менее стремятся к свободному стилю программирования (хотя не всегда идеально ;-)).

c) С обеими библиотеками мы получаем реальный тип календарной даты (называемый LocalDate), реальный тип настенного времени (вызываемый LocalTime) и композицию (вызываемый LocalDateTime). Это очень большая победа по сравнению со старыми java.util.Calendarи java.util.Date.

г) Обе библиотеки используют метод, ориентированный на метод, то есть они поощряют использование пользователем getDayOfYear()вместо get(DAY_OF_YEAR). Это вызывает много дополнительных методов по сравнению с java.util.Calendar(хотя последний не является типобезопасным из-за чрезмерного использования целых).

Производительность

Посмотрите другой ответ @ OO7, указывающий на анализ Михаила Воронцова, хотя пункт 3 (отлов исключений), вероятно, устарел - см. Эту ошибку JDK . Различная производительность (что в целом в пользу JSR-310 ) в основном обусловлена ​​тем фактом, что внутренняя реализация Joda-Time всегда использует подобный машинному времени длинный примитив (в миллисекундах).

Ноль

Joda-Time часто использует NULL в качестве значения по умолчанию для системного часового пояса, языка по умолчанию, текущей метки времени и т. Д., В то время как JSR-310 почти всегда отклоняет значения NULL.

точность

JSR-310 работает с точностью до наносекунды, в то время как Joda-Time ограничена точностью до миллисекунды .

Поддерживаемые поля:

Обзор поддерживаемых полей в Java-8 (JSR-310) дается некоторыми классами во временном пакете (например, ChronoField и WeekFields ), в то время как Joda-Time довольно слаб в этой области - см. DateTimeFieldType . Самым большим недостатком Joda-Time здесь является отсутствие локализованных недельных полей. Общей особенностью дизайна реализации обоих полей является то, что оба основаны на значениях типа long (никаких других типов, даже перечислений).

Enum

JSR-310 предлагает перечисления как DayOfWeekили в Monthто время как Joda-Time не предлагает это, потому что он был в основном разработан в 2002-2004 годах до Java 5 .

API зоны

а) JSR-310 предлагает больше функций часового пояса, чем Joda-Time. Последние не могут дать программный доступ к истории переходов смещения часового пояса, в то время как JSR-310 способен это сделать.

б) Для вашей информации: JSR-310 переместил свой внутренний репозиторий часовых поясов в новое место и другой формат. Старая папка библиотеки lib / zi больше не существует.

Настройщик против Собственности

JSR-310 ввел TemporalAdjuster-интерфейс как формализованный способ экстернализации временных вычислений и манипуляций, особенно для авторов библиотек или фреймворков. Это хороший и относительно простой способ внедрения новых расширений JSR-310 (своего рода эквивалент статического помощника). занятия для бывших java.util.Date).

Однако для большинства пользователей эта функция имеет очень ограниченную ценность, поскольку бремя написания кода по-прежнему лежит на пользователе. Встроенных решений, основанных на новом TemporalAdjuster-concept, не так много, в настоящее время существует только вспомогательный класс TemporalAdjustersс ограниченным набором манипуляций (и перечислений Monthили других временных типов).

Joda-Time предлагает пакет полей, но практика показала, что новые полевые реализации очень трудно кодировать. С другой стороны, Joda-Time предлагает так называемые свойства, которые делают некоторые манипуляции намного проще и элегантнее, чем в JSR-310, например, property.withMaximumValue () .

Календарные системы

JSR-310 предлагает 4 дополнительные календарные системы. Наиболее интересным является Umalqura (используется в Саудовской Аравии). Другие 3: Minguo (Тайвань), японский (только современный календарь с 1871 года!) И ThaiBuddhist (только после 1940 года).

Joda-Time предлагает исламский календарь, основанный на калькуляционной основе, а не календарь, основанный на прицеле, как Umalqura. Тайский буддист также предлагается Joda-Time в аналогичной форме, Minguo и японский нет. В противном случае Joda-Time также предлагает коптский и эфиопский календарь (но без какой-либо поддержки интернационализации).

Более интересно для европейцев: Joda-Time также предлагает григорианский , юлианский и смешанно- григориано -юлианский календарь. Однако практическая ценность для реальных исторических вычислений ограничена, потому что такие важные функции, как разные начала года в истории дат, вообще не поддерживаются (такая же критика действительна для старых java.util.GregorianCalendar).

Другие календари , как иврит или персидские или индус полностью отсутствуют в обеих библиотеках.

Эпоха дней

JSR-310 имеет класс JulianFields, а Joda-Time (версия 2.0) предлагает несколько вспомогательных методов в классе DateTimeUtils .

Часы

У JSR-310 нет интерфейса (ошибка проектирования), но есть абстрактный класс, java.time.Clockкоторый можно использовать для любого внедрения зависимости от часов. Вместо этого Joda-Time предлагает интерфейс MillisProvider и некоторые вспомогательные методы в DateTimeUtils . Таким образом, Joda-Time также может поддерживать тестовые модели с разными часами (издевательства и т. Д.).

Продолжительность арифметики

Обе библиотеки поддерживают расчет временных расстояний в одной или нескольких временных единицах. Однако при обработке длительностей в одну единицу стиль JSR-310 явно лучше (и основывается на длинных, а не на использовании int):

JSR-310 => long days = ChronoUnit.DAYS.between(date1, date2);

Joda-Time => int days = DAYS.daysBetween(date1, date2).getDays();

Обработка множественных длительностей также различна. Даже результаты расчетов могут отличаться - см. Этот закрытый выпуск Joda-Time . В то время как JSR-310 использует очень простой и ограниченный подход для использования только классов Period(продолжительность основана на годах, месяцах и днях) и Duration(на основе секунд и наносекунд), Joda-Time использует более сложный способ использования класса PeriodTypeдля управления в каких единицах должна быть выражена продолжительность (Joda-Time называет это «Период»). В то времяPeriodType-API как-то неловко использовать подобный способ, совсем не предлагаемый JSR-310. В частности, в JSR-310 пока невозможно определить смешанную продолжительность даты и времени (например, на основе дней и часов). Так что будьте осторожны, если речь идет о миграции из одной библиотеки в другую. Обсуждаемые библиотеки несовместимы - несмотря на частично одинаковые имена классов.

Интервалы

JSR-310 не поддерживает эту функцию, в то время как Joda-Time имеет ограниченную поддержку. Смотрите также этот SO-ответ .

Форматирование и анализ

Лучший способ сравнить обе библиотеки - просмотреть классы с одинаковыми именами DateTimeFormatterBuilder (JSR-310) и DateTimeFormatterBuilder (Joda-Time). Вариант JSR-310 немного более мощный (он также может обрабатывать любой тип, TemporalFieldесли полевой разработчик сумел закодировать некоторые точки расширения, такие как resol () ). Однако самое важное отличие - на мой взгляд:

JSR-310 может намного лучше анализировать имена часовых поясов (символ шаблона формата z), в то время как Joda-Time вообще не могла этого делать в своих более ранних версиях и теперь только в очень ограниченном виде.

Еще одним преимуществом JSR-310 является поддержка автономных названий месяцев, что важно для таких языков, как русский или польский и т. Д. Joda-Time не имеет доступа к таким ресурсам - даже на платформах Java-8.

Синтаксис шаблона в JSR-310 также более гибкий, чем в Joda-Time, допускает наличие необязательных секций (используя квадратные скобки), более ориентирован на стандарт CLDR и предлагает заполнение (буквенный символ p) и больше полей.

В противном случае следует отметить, что Joda-Time может форматировать длительности с использованием PeriodFormatter . JSR-310 не может этого сделать.


Надеюсь, этот обзор поможет. Вся собранная информация в основном там благодаря моим усилиям и исследованиям, как спроектировать и внедрить лучшую библиотеку даты и времени (ничто не идеально).

Обновление от 2015-06-24:

Тем временем я нашел время, чтобы написать и опубликовать табличный обзор для разных временных библиотек на Java. Таблицы также содержат сравнение между Joda-Time v2.8.1 и Java-8 (JSR-310). Это более подробно, чем этот пост.

Мено Хохшильд
источник
12
Это выдающийся пост. Большое спасибо, чтобы поделиться всей этой информацией. Если бы вам дали выбор между Joda и JSR-310 (только для ванильных вариантов использования), что бы вы выбрали? Я стою перед этим выбором прямо сейчас. Я рассматриваю JSR-310 только потому, что он более новый, и я стараюсь поддерживать «движение вперед», где это возможно.
Кевинарпе
7
@kevinarpe Если бы у меня был только выбор между JSR-310 и Joda-Time, я бы, вероятно, предпочел JSR-310, потому что Joda-Time почти прекратил дальнейшее развитие (новых больших возможностей ожидать не приходится - просто исправление ошибок и небольшие обновления). И дизайн JSR-310 просто более современный (и с лучшим внутренним качеством). Между прочим, что неудивительно, однако, мое реальное решение скорее отдать предпочтение моей собственной библиотеке Time4J - см. Также ссылку на табличный обзор, приведенный внизу моего поста. Всегда хорошо иметь альтернативы, и это сильно зависит от того, какие функции вам нужны.
Мено Хохшильд
Разве Duration не является версией Java8 для Interval?
Кристиан Худжер
1
@ChristianHujer Нет, java.time.Durationнельзя запрашивать его начало или конец, в отличие от интервала, который привязан к временной шкале. Этот тип JSR-310 представляет собой просто пару прошедших секунд и наносекунд с момента неизвестного старта.
Мено Хохшильд
42

Java 8 Дата / Время:

  1. Java 8 классы построены вокруг человеческого времени. Это делает их быстрыми для арифметики и преобразования даты и времени.
  2. Получатели компонента даты / времени, такие как, getDayOfMonthимеют сложность O (1) в реализации Java 8.
  3. Синтаксический анализ OffsetDateTime/ OffsetTime/ ZonedDateTimeвыполняется очень медленно в Java 8 и b121 из-за исключительных ситуаций, возникающих внутри JDK.
  4. Набор пакетов: java.time.*, java.time.chrono.*, java.time.format.*, java.time.temporal.*,java.time.zone.*
  5. Экземпляры (временные метки) Дата и время Частичное Дата и время Парсер и форматер Часовые пояса Различные хронологии (календари).
  6. Существующие классы имеют проблемы, такие как Date не поддерживает I18N или L10N. Они изменчивы!
  7. Проще и надежнее.
  8. Часы могут быть введены.
  9. Часы могут быть созданы с различными свойствами - Статические часы, Смежные часы, Часы с низкой точностью (целые секунды, целые минуты и т. Д.).
  10. Часы могут быть созданы с определенными часовыми поясами. Clock.system(Zone.of("America/Los_Angeles")),
  11. Делает тестирование даты и времени обработки кода.
  12. Делает тесты независимыми от часового пояса.

Joda-Time:

  1. Joda-Time использует машинное время внутри. Ручная реализация, основанная на значениях int / long, будет намного быстрее.
  2. Получатели Joda-Time требуют вычисления времени от компьютера к человеку для каждого вызова получателя, что делает Joda-Time узким местом в таких сценариях.
  3. Он состоит из неизменяемых классов, которые он обрабатывает Instants, Date & Time, Partials и Durations. Он гибкий. Он хорошо спроектирован.
  4. Представляет даты как моменты. Но дата и время могут соответствовать более чем одному мгновению. Час перекрытия, когда заканчивается летнее время. А также не имеют ни одного момента, который ему соответствует вообще. Разрыв в час, когда начинается дневной свет. Должен выполнять сложные вычисления для простых операций.
  5. Принимает пустые значения в качестве допустимых значений в большинстве своих методов. Приводит к тонким ошибкам.

Для более детального сравнения смотрите:

Производительность библиотеки даты / времени Java 8 (а также Joda-Time 2.3 и juCalendar) . & Новый API даты и времени в Java 8

OO7
источник
Когда вы говорите «Делает тесты независимыми от часового пояса». Что именно вы подразумеваете под этим?
Zack
@Zack: Вероятно, если вы тестируете код, который ведет себя по-разному в зависимости от часового пояса, вам может потребоваться принудительно запустить тест с другим часовым поясом по умолчанию, отличным от того, который предоставляется операционной системой.
jarnbjo
Хах - я думал, ты сказал, что Йода внутренне работал на машине времени, а не на машине времени ... И я не удивлюсь
Kyranstar
4
@ OO7 Что значит "человеческое время"? Время вычисляется на машинах в любом случае.
Игорь Ганапольский
1

Joda-Time сейчас в режиме обслуживания

Не прямой ответ на вопрос, но проект Joda-Time больше не находится в активной разработке. Команда предлагает пользователям перейти на более новый API java.time . Смотрите учебник по Oracle .

С официальной страницы проекта GitHub :

Joda-time больше не находится в активной разработке, кроме как для того, чтобы обновлять данные о часовых поясах. Начиная с Java SE 8, пользователей просят перейти на java.time (JSR-310) - основную часть JDK, которая заменяет этот проект. Для пользователей Android java.time добавлен в API 26+. Проекты, которым требуется поддержка более низких уровней API, могут использовать библиотеку ThreeTenABP.

Saikat
источник