288

java.util.Dateと Joda-Timeに関する質問があることは承知しています。しかし、掘り下げた後、 java.time API ( Java 8の新機能、 JSR 310で定義) とJoda-Timeの違いに関するスレッドを見つけることができませんでした。

Java 8 の java.time API はよりクリーンで、Joda-Time よりもはるかに多くのことができると聞いています。しかし、この 2 つを比較する例は見つかりません。

  • Joda-Time ができないことで java.time ができることは何ですか?
  • java.time で Joda-Time よりも優れている点は何ですか?
  • java.time を使用するとパフォーマンスが向上しますか?
4

4 に答える 4

452

共通機能

a) どちらのライブラリも不変型を使用します。Joda-Time は、 のような追加の変更可能な型も提供しますMutableDateTime

b) さらに: 両方のライブラリは、Eric Evans の設計研究「TimeAndMoney」、またはドメイン駆動スタイルに関する Martin Fowlerのアイデアに触発されているため、多かれ少なかれ流暢なプログラミング スタイルを目指して努力しています(常に完璧であるとは限りません ;-))。

c) 両方のライブラリを使用して、実際のカレンダー日付タイプ ( と呼ばれるLocalDate)、実際の壁時間タイプ ( と呼ばれるLocalTime)、および構成 ( と呼ばれるLocalDateTime) を取得します。これは、古いものjava.util.Calendarjava.util.Date.

d) どちらのライブラリもメソッド中心のアプローチを使用しており、ユーザーがgetDayOfYear()代わりに使用することを奨励していますget(DAY_OF_YEAR)。これにより、 と比較して多くの余分なメソッドが発生しますjava.util.Calendar(ただし、後者は int を過度に使用するため、タイプセーフではありません)。

パフォーマンス

ポイント3(例外キャッチ)はおそらく時代遅れですが、Mikhail Vorontsovの分析を指している@OO7による他の回答を参照してください-このJDK-bugを参照してください。異なるパフォーマンス (一般的にJSR-310に有利) は、主にJoda-Timeの内部実装が常にマシンタイムのような長いプリミティブ (ミリ秒単位) を使用するという事実によるものです。

ヌル

Joda-Time はシステム タイムゾーン、デフォルト ロケール、現在のタイムスタンプなどのデフォルトとして NULL を使用することがよくありますが、JSR-310 はほとんど常に NULL 値を拒否します。

精度

JSR-310 はナノ秒の精度を処理しますが、Joda-Time はミリ秒の精度に制限されています。

サポートされるフィールド:

Java-8 (JSR-310) でサポートされているフィールドの概要は、temporal-package ( ChronoFieldWeekFieldsなど) のいくつかのクラスによって提供されますが、Joda-Time はこの分野ではかなり弱いです - DateTimeFieldTypeを参照してください。Joda-Time の最大の欠点は、ローカライズされた週関連のフィールドがないことです。両方のフィールド実装設計の共通点は、どちらも long 型の値に基づいていることです (他の型はなく、列挙型もありません)。

列挙型

JSR-310 はorのような列挙型を提供しますが、Joda-Time は主にJava 5より前の 2002 年から 2004 年に開発されたため、これを提供しません。DayOfWeekMonth

ゾーン API

a) JSR-310 は、Joda-Time よりも多くのタイムゾーン機能を提供します。JSR-310 はこれを行うことができますが、後者はタイムゾーン オフセット遷移の履歴へのプログラムによるアクセスを生成できません。

b) 参考までに: JSR-310 は、内部のタイムゾーン リポジトリを新しい場所と別の形式に移動しました。古いライブラリ フォルダ lib/zi はもう存在しません。

アジャスター vs. プロパティ

JSR-310 は、TemporalAdjuster一時的な計算と操作を外部化するための形式化された方法として -interface を導入しました。これは、特にライブラリまたはフレームワークの作成者にとって、JSR-310 の新しい拡張機能を埋め込むための優れた比較的簡単な方法です (静的ヘルパーに相当するものです)。前者のクラスjava.util.Date)。

ただし、ほとんどのユーザーにとって、この機能の価値は非常に限られています。これは、コードを記述する負担が依然としてユーザーにあるためです。新しい -concept に基づく組み込みソリューションTemporalAdjusterはそれほど多くはありません。現在TemporalAdjusters、限定された一連の操作 (および enumMonthまたはその他の一時的な型) を持つヘルパー クラスしかありません。

Joda-Time はフィールド パッケージを提供しますが、新しいフィールドの実装はコーディングが非常に難しいという証拠が示されています。一方、Joda-Time は、一部の操作を JSR-310 よりもはるかに簡単かつエレガントにするいわゆるプロパティを提供します (例: property.withMaximumValue() )

暦法

JSR-310 は、4 つの追加のカレンダー システムを提供します。最も興味深いのはUmalqura (サウジアラビアで使用) です。他の 3 つは、民国(台湾)、日本語 (1871 年以降の現代暦のみ!)、タイ仏教(1940 年以降のみ正しい) です。

Joda-Time は、Umalqura のような目撃情報に基づくカレンダーではなく、計算ベースに基づくイスラム暦を提供します。タイ仏教も同様の形式で Joda-Time によって提供されていますが、Minguo と日本のものはそうではありません。それ以外の場合、Joda-Time はコプト暦とエチオピア暦も提供します (ただし、国際化はサポートされていません)。

ヨーロッパ人にとってはさらに興味深い: Joda-Time は、グレゴリオ暦ユリウス暦、およびグレゴリオ暦とユリウス暦が混在するカレンダーも提供しています。ただし、実際の履歴計算の実用的な価値は限られています。これは、日付履歴の異なる年の開始などの重要な機能がまったくサポートされていないためです (同じ批判が old にも当てはまりますjava.util.GregorianCalendar)。

ヘブライ語ペルシャ語ヒンドゥー語などの他のカレンダーは、両方のライブラリに完全にありません。

エポック日

JSR-310 にはクラスJulianFieldsがあり、Joda-Time (バージョン 2.0) にはクラスDateTimeUtilsでいくつかのヘルパー メソッドが用意されています。

時計

java.time.ClockJSR-310 にはインターフェース (設計ミス) はありませんが、任意のクロック依存性注入に使用できる抽象クラスがあります。Joda -Time は代わりにMillisProviderインターフェイスとDateTimeUtilsのいくつかのヘルパー メソッドを提供します。したがって、このように Joda-Time は、異なるクロック (モックなど) を使用したテスト駆動モデルもサポートできます。

デュレーション演算

どちらのライブラリも、1 つ以上の時間単位での時間距離の計算をサポートしています。ただし、単一単位期間を処理する場合は、JSR-310 スタイルの方が明らかに優れています (int を使用する代わりに long ベース):

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

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

複数ユニット期間の扱いも異なります。計算結果も異なる場合があります - このクローズドJoda-Time issueを参照してください。PeriodJSR-310 はクラス(年、月、日に基づく期間) および(秒とナノ秒に基づく)のみを使用する非常に単純で制限されたアプローチを使用しますがDuration、Joda-Time はクラスを使用しPeriodTypeて制御するためのより洗練された方法を使用します。期間 (Joda-Time では「期間」と呼びます) を表す単位。一方、PeriodType-APIは、JSR-310ではまったく提供されていない同様の方法を使用するのがどういうわけか厄介です。特に、JSR-310 では、日付と時刻の混合期間 (たとえば、日と時間に基づく) を定義することはまだできません。そのため、あるライブラリから別のライブラリへの移行に関しては注意が必要です。議論中のライブラリは、部分的に同じクラス名にもかかわらず、互換性がありません。

間隔

JSR-310 はこの機能をサポートしていませんが、Joda-Time はサポートが制限されています。このSO-answerも参照してください。

フォーマットと解析

両方のライブラリを比較する最善の方法は、同じ名前のクラスDateTimeFormatterBuilder (JSR-310) とDateTimeFormatterBuilder (Joda-Time) を表示することです。JSR-310 バリアントはもう少し強力です (フィールドの実装者がresolve()TemporalFieldのようないくつかの拡張ポイントをコーディングできれば、あらゆる種類のものも処理できます)。ただし、最も重要な違いは、私の意見では次のとおりです。

JSR-310 はタイムゾーン名 (フォーマット パターン シンボル z) をより適切に解析できますが、Joda-Time は以前のバージョンではこれをまったく行うことができず、現在は非常に限られた方法でのみ行うことができます。

JSR-310 のもう 1 つの利点は、ロシア語やポーランド語などの言語で重要なスタンドアロンの月名のサポートです。Joda-Time は、Java-8 プラットフォームでさえ、そのようなリソースにアクセスできません。

JSR-310 のパターン構文は、Joda-Time よりも柔軟で、オプションのセクション (角括弧を使用) を許可し、CLDR 標準に向けられており、パディング (文字記号 p) とより多くのフィールドを提供しています。

それ以外の場合、 Joda-Time はPeriodFormatterを使用して期間をフォーマットできることに注意してください。JSR-310 はこれを行うことができません。


この概要がお役に立てば幸いです。収集されたすべての情報は、主に、より優れた日時ライブラリを設計および実装するための私の努力と調査の結果です (完璧なものはありません)。

2015 年 6 月 24 日からの更新:

その間、Java でさまざまな時間ライブラリの表形式の概要を作成して公開する時間を見つけました。この表には、Joda-Time v2.8.1 と Java-8 (JSR-310) の比較も含まれています。この投稿よりも詳細です。

于 2014-07-08T15:20:43.547 に答える
44

Java 8 日付/時刻:

  1. Java 8 クラスは人間の時間を中心に構築されています。これにより、人間の日時演算/変換が高速になります。
  2. 日付/時刻コンポーネントの gettergetDayOfMonthは、Java 8 実装で O(1) の複雑さを持っています。
  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. テストをタイムゾーンに依存しないようにします。

Joda-Time :

  1. Joda-Time は内部でマシンタイムを使用しています。int/long 値に基づく手動実装は、はるかに高速です。
  2. Joda-Time ゲッターは、getter 呼び出しごとにコンピューターから人間への時間計算を必要とするため、このようなシナリオでは Joda-Time がボトルネックになります。
  3. Instants、Date & Time、Partials、および Durations を処理する不変クラスで構成されています。柔軟性があり、よく設計されています。
  4. 日付をインスタントとして表します。ただし、日付と時刻は複数のインスタントに対応する場合があります。サマータイムが終了する重複時間。それに対応する瞬間もまったくありません。昼光が始まるギャップアワー。単純な操作のために複雑な計算を実行する必要があります。
  5. ほとんどのメソッドで有効な値として null を受け入れます。微妙なバグにつながります。

詳細な比較については、次を参照してください:-

Java 8 日付/時刻ライブラリのパフォーマンス (および Joda-Time 2.3 と juCalendar)。& Java 8 の新しい日付と時刻の API

于 2014-07-08T13:35:36.007 に答える