Відмінності між API Java 8 Date Time (java.time) та Joda-Time


264

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

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

  • Що може зробити java.time, що Joda-Time не може?
  • Що може зробити java.time кращим, ніж Joda-Time?
  • Чи кращі показники роботи з java.time?

8
Це не так, що стосується Java 7, а не Java 8. Відповідь на це питання була відредагована для Java 8 з дуже маленькими деталями. Моє запитання - це питання про новий API DateTime Java 8, а не Java-java.util.Date Java 7. Я просто шукаю відповідь, яка порівнює Java 8 з JodaTime.
Зак

2
можливо, цей документ Oracle може вам допомогти.
MarioDS

Якщо у вас Java 7, використовуйте додаткову бібліотеку, якщо у вас є Java 8, використовуйте вбудовану бібліотеку. Оскільки обидві бібліотеки в основному розроблені однією людиною, я не впевнений, які основні відмінності ви очікуєте.
Пітер Лоурі

2
@PeterLawrey: API Joda-Time та API для дати та часу Java 8 насправді зовсім інші.
jarnbjo

5
Ви також можете прочитати цю публікацію в блозі від Стівена Колбурна - основного автора обох проектів.
Метт Джонсон-Пінт

Відповіді:


416

Загальні риси

а) Обидві бібліотеки використовують незмінні типи. Joda-Time також пропонує додаткові типи змінних, наприклад MutableDateTime.

b) Крім того: обидві бібліотеки натхненні дизайнерським дослідженням "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 (жодних інших типів, навіть не перерахунків).

Енум

JSR-310 пропонує переліки на зразок DayOfWeekабо Monthпоки Joda-Time цього не пропонує, оскільки він був в основному розроблений у 2002-2004 роках до Java 5 .

API зони

a) JSR-310 пропонує більше функцій часового поясу, ніж Joda-Time. Latter не в змозі отримати програмний доступ до історії переходів часового поясу, тоді як JSR-310 спроможний це зробити.

b) Для вашої інформації: JSR-310 перемістив своє внутрішнє сховище часового поясу на нове місце та інший формат. Стара бібліотека lib / zi вже не існує.

Налаштування проти власності

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

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

Joda-Time пропонує польовий пакет, але практика показала, що нові польові реалізації дуже важко кодувати. З іншого боку, Joda-Time пропонує так звані властивості, які роблять деякі маніпуляції набагато простішими та елегантнішими, ніж у JSR-310, наприклад, property.withMaximumValue () .

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

JSR-310 пропонує 4 додаткові календарні системи. Найцікавіший - Умальква (використовується в Саудівській Аравії). Інші 3: Minguo (Тайвань), японський (лише сучасний календар з 1871 року!) Та ThaiBuddhist (правильний лише після 1940 року).

Joda-Time пропонує ісламський календар на основі калькуляційної бази, а не календаря, який базується на прицілі, як Умальква. Тайський-буддистський також пропонує 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 має обмежену підтримку. Дивіться також цю відповідь .

Форматування та розбір

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

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

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

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

В іншому випадку слід зазначити, що Joda-Time може форматувати тривалість за допомогою PeriodFormatter . JSR-310 цього не може зробити.


Сподіваюся, цей огляд допомагає. Уся зібрана інформація є, головним чином, завдяки моїм зусиллям та розслідуванням, як створити та впровадити кращу бібліотеку з датами та часом (нічого не ідеального).

Оновлення від 24.06.2015:

Тим часом я знайшов час писати та публікувати табличний огляд для різних бібліотек часу на 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 - див. Також посилання на табличний огляд, наведений внизу моєї публікації. Завжди добре мати альтернативи, і це сильно залежить від того, які функції вам потрібні.
Meno Hochschild

Чи не є версія інтервалу Java8 тривалістю?
Крістіан Худжер

1
@ChristianHujer Ні, java.time.Durationне можна запитувати його початок чи кінець, на відміну від інтервалу, який закріплений на часовій шкалі. Цей тип JSR-310 - це лише пара минулих секунд і наносекунд з невідомого початку.
Meno Hochschild

42

Дата / час Java 8:

  1. Класи Java 8 побудовані в часи людини. Це робить їх швидкими для арифметики / перетворення дат людини.
  2. Дані / час, такі як складові, getDayOfMonthмають складність O (1) в реалізації Java 8.
  3. Розбір роботи OffsetDateTime/ OffsetTime/ ZonedDateTimeу Java 8 ea 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. Робить тести незалежними від часового поясу.

Час Джода:

  1. Joda-Time використовує машинний час всередині. Ручна реалізація, заснована на значеннях int / long, була б набагато швидшою.
  2. Отриманці часу Joda вимагають обчислення часу від комп'ютера до людини на кожен дзвінок, який робить виклик, що робить Joda-Time вузьким місцем у таких сценаріях.
  3. Він складається з непорушних класів, з якими він обробляє моменти, дату та час, партії та тривалість. Він гнучкий, добре розроблений.
  4. Представляє дати як екземпляри. Але дата та час можуть відповідати більше однієї миті. Година, що перекривається, коли закінчується літній час. А також не мати жодної миті, яка б їй відповідала взагалі. Проміжок години, коли починається денне світло. Доводиться виконувати складні обчислення для простих операцій.
  5. Приймає нулі як дійсні значення більшості своїх методів. Приводить до тонких помилок.

Для більш детального порівняння див:

Продуктивність бібліотеки Java 8 Дата / Час (а також Joda-Time 2.3 та juCalendar) . & Новий API дати та часу на Java 8


Коли ви говорите "Робить тести незалежними від часового поясу". Що саме ви маєте на увазі під цим?
Зак

@Zack: Можливо, якщо ви перевірите код, який веде себе по-різному, залежно від часового поясу, вам може знадобитися змусити тест запуститись з іншим часовим поясом за замовчуванням, ніж те, що передбачено операційною системою.
jarnbjo

Ага - я думав, ти сказав, що джода внутрішньо працює на машині часу, а не в машинний час ... І я не здивуюсь
Kyranstar

4
@ OO7 Що ти означає "час людини"? Час обчислюється машинами в будь-якому випадку.
ІгорГанапольський

1

Joda-Time зараз у режимі обслуговування

На питання це не пряма відповідь, але проект Joda-Time вже не активно розвивається. Команда пропонує користувачам перейти на новіший API java.time . Дивіться підручник від Oracle .

На офіційній сторінці проекту GitHub :

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.