私は最近、Javaで日付を操作するための非常に単純なライブラリ(基本的には単一のクラス)であるdate4jに出くわしました。概念的には、date4jの「アイデア」が本当に好きです。実際、メインサイト全体とjavadocのドキュメントの両方を読んだ後、私は述べられているすべてにほぼ同意します。
さて、date4jを使用すべきでない理由はいくつかあるかもしれません-バグ、パフォーマンス、ユーザーの不足などです。私はそれらのことについて質問していません。概念的には、date4j(そこにあるほとんどのアプリケーション)のアイデアの何が問題になっていますか?確かに、jodaやthreetenのようなものを必要とするアプリケーションがあるかもしれませんが、それらは少数派であると私は信じています。
日付/時刻を扱うユーザー(ほとんどすべての人がJavaアプリを作成している)に人々が与える通常のアドバイスは、次のようなものです。
- java.util.Calendarの代わりにjoda-timeを使用する
- WebサーバーをUTCに設定します
- データベースサーバーをUTCに設定します
- 日時をUTCで保存します
実際、最後の3つの箇条書きは、日付を操作するときに人々が抱える現在のメンタルモデルの問題を示しています。人々は、アプリケーションレベルとデータベースレベルの両方でタイムゾーンを管理しようとします(ORMフレームワークは、物事をさらに複雑にする別の抽象化レイヤーを追加することは言うまでもありません)。
あなたはそれらのことをする必要はないはずです。たとえば、java.util.Calendarを使用していて、ユーザー定義のタイムゾーンで時間を操作している場合は、次のようになります。
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
c.set(Calendar.YEAR, 2011);
c.set(Calendar.MONTH, 0);
c.set(Calendar.DAY_OF_MONTH, 1);
c.set(Calendar.HOUR_OF_DAY, 3);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
これは、タイムゾーンに関係なく、時間の「インスタント」を表します。今回は、データベースとの間で「変換」が発生することを心配せずに永続化できるはずです。データベースが上海のタイムゾーンにあり、Webサーバーがロサンゼルスのタイムゾーンにあるかどうかは関係ありません。時間の瞬間は関係なく同じです。
1つの問題は、一部のデータベースがタイムゾーンを管理しようとし(私はあなたを見ています、Postgres!grr!)、さらに悪いことに、JDBCドライバーレベルでの動作はベンダー固有です(つまり、PreparedStatement.setDate / getDate)。
date4jが使用するメンタルモデルは、すべての混乱を取り除くようです。たとえば、now()を呼び出すときに、明示的に使用を強制してタイムゾーンを提供します。このサイトには、ライブラリを使用するための非常に優れた推奨事項がいくつかあります(これらは、以前に自分のアプリですでに行っていたものです)。
- タイムゾーンを管理しようとするデータベースタイプを使用しないでください
- タイムゾーンを別の列として保存する(必要な場合)
date4jのようなライブラリを採用する人が増えないのはなぜですか?