回答:
ああ、Java Date
クラス。おそらく、どの言語でもどこでも何もしないようにする方法の最も良い例の1つでしょう。どこから始めますか?
JavaDocを読むと、開発者が実際に良いアイデアを持っていると考えるようになるかもしれません。UTCとの違いについてとGMT二つの違いは基本的に(起こらない秒飛躍されているにもかかわらず、長さでかなり めったにが)。
ただし、設計上の決定は、適切に設計されたAPIであるという考えを無駄にすることになります。ここでは、よくある間違いをいくつか紹介します。
null
ます。その結果、0..11(今日は109年の月11)になります。文字列に変換するために、同様の数の++と-が月にあります。Calendar
を「修正」するように設計されたは、実際には同じ間違いを犯します。彼らはまだ変更可能です。Date
を表す DateTime
ますが、SQLランドのそれらを順守するためにjava.sql.Date
、1日を表す別のサブクラスがあります(ただし、タイムゾーンは関連付けられていません)。TimeZone
関連付けられたはないDate
ため、範囲(「終日」など)はしばしば真夜中-真夜中(しばしば任意のタイムゾーン)として表されます最後に、うるう秒は一般に、1時間以内にntpで更新される適切なシステムクロックに対して自動的に修正されることに注意してください(以下のリンクを参照)。2うるう秒(実際には数年ごとに最低6か月ごと)が導入されてもシステムが稼働し続ける可能性はほとんどありません。特に、新しいバージョンのコードを時々再デプロイする必要があるという事実を考慮すると、 。クラスを再生成する動的言語やWARエンジンのようなものを使用しても、クラススペースが汚染され、最終的にpermgenが不足します。
Java 8 でjava.timeを使用して古い日時クラスを置き換えたJSR 310は、次のように元のJSRで正当化されます。
2.5提案された仕様では、Javaコミュニティのどのようなニーズに対応しますか?
現在、Java SEには、java.util.Dateとjava.util.Calendarという2つの別個の日時APIがあります。両方のAPIは、Java開発者がウェブログやフォーラムで使用するのが難しいと一貫して説明されています。特に、両方とも数か月間ゼロインデックスを使用するため、多くのバグが発生します。カレンダーは、主にその状態を内部で2つの異なる方法で保存するため、長年にわたって多くのバグとパフォーマンスの問題に悩まされてきました。
1つの古典的なバグ(4639407)により、特定の日付がCalendarオブジェクトに作成されませんでした。一部のユーザーが正しい生年月日を入力できないようにする効果がある、一部の年では日付を作成できるが他の年では作成できない一連のコードを書くことができます。これは、Calendarクラスが夏の夏時間の1時間の増加しか許さなかったために発生しました。このバグは修正されましたが、将来、ある国で夏時間に3時間の夏時間の追加が導入された場合、Calendarクラスは再び機能しなくなります。
現在のJava SE APIは、マルチスレッド環境でも問題があります。不変クラスは、状態を変更できないため、本質的にスレッドセーフであることが知られています。ただし、日付とカレンダーはどちらも変更可能であるため、プログラマーは複製とスレッド化を明示的に考慮する必要があります。さらに、DateTimeFormatにスレッドセーフ性がないことは広く知られていないため、スレッド化の問題を追跡するのが難しい多くの原因となっています。
Java SEが日時に対して持つクラスの問題に加えて、Java SEには他の概念をモデル化するためのクラスがありません。非タイムゾーンの日付または時刻、期間、期間、および間隔は、Java SEではクラス表現を持ちません。その結果、開発者は頻繁にintを使用して期間を表し、javadocで単位を指定します。
包括的な日時モデルがないため、多くの一般的な操作が本来よりも扱いにくくなっています。たとえば、2つの日付間の日数を計算することは、現在のところ特に難しい問題です。
このJSRは、日付と時刻(タイムゾーンの有無にかかわらず)、期間と期間、間隔、フォーマット、解析を含む完全な日付と時刻モデルの問題に取り組みます。
私はあなたのために感じます...以前の.NETプログラマーとして、私は同じ質問をしました。.NETのタイムAPI(タイムスパン、オペレーターのオーバーロード)は非常に便利です。
まず、特定の日付を作成するには、廃止されたAPIを使用するか、次のいずれかを行います。
Calendar c = Calendar.getInstance();
c.set(2000, 31, 12)
1日を引くには、次のような悪事を行います
Date firstDate = ...
Calendar c = Calendar.getInstance();
c.setTime(fistDate);
c.add(Calendar.DATE,-1);
Date dayAgo = c.getTime();
または悪い
Date d = new Date();
Date d2 = new Date(d.getTime() - 1000*60*60*24);
2つの日付の間に経過した日数(日/週/月)を確認するには...さらに悪化します
ただし、Apache()のDateUtilsにはorg.apache.commons.lang.time.DateUtils
便利なメソッドがいくつかあり、最近ではそれらだけを使用していることに気付きました
Brabsterが書いたように、Joda Timeも優れた外部ライブラリですが、Apacheは他の何よりも「一般的」に見えます...