Java 8 Date Time API(java.time)とJoda-Timeの違い


264

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

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

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

8
それは、Java 8ではなく、Java 7に関係するものではありません。この質問への回答は、Java 8向けに編集されており、詳細はほとんどありません。具体的には、Java 7のjava.util.Dateではなく、Java 8の新しいDateTime APIについて質問します。Java 8とJodaTimeを比較する答えを探しています。
ザック2014

2
おそらく、このOracleドキュメントが役立ちます。
MarioDS 2014

Java 7を使用している場合は追加のライブラリを使用し、Java 8を使用している場合は組み込みライブラリを使用します。どちらのライブラリも基本的には同じ人物が設計しているため、どのような大きな違いが予想されるかはわかりません。
Peter Lawrey、2014

2
@PeterLawrey:Joda-TimeとJava 8の日時APIは実際にはかなり異なります。
jarnbjo 14

5
このブログ投稿は、両方のプロジェクトの主著者であるスティーブンコルボーンからも読むことができます。
Matt Johnson-Pint 2014

回答:


416

一般的な機能

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

b)さらに:どちらのライブラリも、Eric Evansのデザインスタディ「TimeAndMoney」またはMartin Fowlerのドメイン駆動型スタイルに関するアイデアに触発されているため、流暢なプログラミングスタイルを目指して努力しています(ただし、常に完璧とは限りませんが;-))。

c)両方のライブラリで、実際のカレンダー日付タイプ(と呼ばれるLocalDate)、実際の壁時間タイプ(と呼ばれるLocalTime)、および構成(と呼ばれるLocalDateTime)を取得します。それは古いものjava.util.Calendarと比較して非常に大きな勝利java.util.Dateです。

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

パフォーマンス

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

ヌル

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

精度

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

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

ジャワ-8(JSR-310)でサポートされているフィールドの概要は、(例えば、時間-パッケージにいくつかのクラスで与えられるChronoFieldWeekFields Jodaのタイムがこの領域にやや弱いながら) -参照DateTimeFieldTypeを。Joda-Timeの最大の欠如は、ローカライズされた週関連のフィールドがないことです。両方のフィールド実装設計の共通の特徴は、両方がlong型(他の型ではなく、列挙型でもない)の値に基づいていることです。

列挙型

JSR-310申し出の列挙型は好きDayOfWeekMonthジョダ-時間がこれを提供していませんが、それは主に前の年の2002年から2004年に開発されたため、Java 5の

ゾーンAPI

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

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

アジャスターとプロパティ

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

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

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

カレンダーシステム

JSR-310は4つの追加カレンダーシステムを提供します。最も興味深いのはウマルクラ(サウジアラビアで使用)です。他の3つは、Minguo(台湾)、日本語(1871年以降のモダンカレンダーのみ!)、ThaiBuddhist(1940年以降のみ正しい)です。

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

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

ヘブライ語ペルシア語ヒンドゥー教のような他のカレンダーは、両方のライブラリで完全に欠落しています。

エポックデー

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

時計

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

期間の計算

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

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

ジョーダタイム=> 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-answerも参照してください。

書式設定と解析

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

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

JSR-310のもう1つの利点は、ロシア語やポーランド語などの言語で重要なスタンドアロンの月名をサポートすることです。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を検討していますが、それはそれがより新しいという理由だけで、可能な限り「前進する」ことをサポートしようとするからです。
kevinarpe 2015

7
@kevinarpe JSR-310とJoda-Timeのどちらかしか選択できない場合は、Joda-Timeがこれ以上の開発をほぼ停止しているため、おそらくJSR-310を選択します(新しい大きな機能は期待できません-バグ修正と小さな更新のみ)。また、JSR-310の設計は、よりモダンなものになっています(内部品質も優れています)。ちなみに、当然のことですが、私の本当の決定は、むしろ自分のライブラリTime4Jを優先することです。私の投稿の下部にある表形式の概要へのリンクも参照してください。代替手段があることは常に良いことであり、必要な機能に大きく依存します。
Meno Hochschild、2015

期間のJava8バージョンの期間ではありませんか?
Christian Hujer 16

1
@ChristianHujerいいえ、java.time.Durationタイムラインに固定されている間隔とは対照的に、開始または終了を照会できません。このJSR-310タイプは、不明な開始からの経過秒とナノ秒のペアにすぎません。
Meno Hochschild、

42

Java 8の日付/時刻:

  1. Java 8クラスは人間の時代を中心に構築されています。人間の日時演算/変換で高速になります。
  2. のような日付/時刻コンポーネントのゲッターgetDayOfMonthは、Java 8実装でO(1)の複雑さを持っています。
  3. Java 8 ea b121では、JDKの内部でスローおよびキャッチされる例外のため、OffsetDateTime/ OffsetTime/の解析ZonedDateTimeが非常に遅くなります。
  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-Timeゲッターでは、ゲッターの呼び出しごとにコンピューターから人間までの時間を計算する必要があるため、このようなシナリオではJoda-Timeがボトルネックになります。
  3. それは、インスタント、日付と時刻、部分、および期間を処理する不変のクラスで構成されています。
  4. 日付をインスタントとして表します。ただし、日付と時刻は複数のインスタントに対応する場合があります。夏時間が終了するオーバーラップ時間。それに対応するインスタントもまったくありません。日光が始まるギャップ時間。単純な操作のために複雑な計算を実行する必要があります。
  5. ほとんどのメソッドでnullを有効な値として受け入れます。微妙なバグにつながります。

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

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


「タイムゾーンに関係なくテストを行う」と言うとき。それはどういう意味ですか?
ザック

@Zack:タイムゾーンに応じて異なる動作をするコードをテストする場合、オペレーティングシステムが提供するタイムゾーンとは異なるデフォルトのタイムゾーンでテストを強制的に実行する必要がある可能性があります。
jarnbjo 14

Hah-jodaは内部的にマシンタイムではなくタイムマシンで実行されているとおっしゃっていたと思います...そして、驚かないでしょう
Kyranstar

4
@ OO7「人間の時間」とはどういう意味ですか?時間はとにかくマシンによって計算されます。
IgorGanapolsky 2015

1

Joda-Timeがメンテナンスモードになりました

質問への直接的な回答ではありませんが、Joda-Timeプロジェクトは活発に開発されていません。チームは、ユーザーが新しいjava.time APIに移行することを提案しています。Oracleによるチュートリアルを参照してください。

公式のGitHubプロジェクトページから:

Joda-timeは、タイムゾーンデータを最新の状態に保つことを除いて、活発に開発されていません。Java SE 8以降、ユーザーはjava.time(JSR-310)(このプロジェクトを置き換えるJDKのコアパーツ)に移行するように求められます。Androidユーザーの場合、java.timeがAPI 26以降で追加されています。より低いAPIレベルをサポートする必要があるプロジェクトは、ThreeTenABPライブラリを使用できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.