1. ホーム

[解決済み】Java。Dateコンストラクタはなぜ非推奨なのですか、そして代わりに何を使えばいいのですか?

2022-04-15 10:11:29

質問

私はC#の世界から来たので、Javaはまだあまり経験がありません。Eclipseから、次のように言われました。 Date は非推奨となりました。

Person p = new Person();
p.setDateOfBirth(new Date(1985, 1, 1));

なぜ?また、代わりに何を(特に上記のような場合)使うべきでしょうか?

どのように解決するのですか?

tl;dr

LocalDate.of( 1985 , 1 , 1 )

...または...

LocalDate.of( 1985 , Month.JANUARY , 1 )

詳細

java.util.Date , java.util.Calendar および java.text.SimpleDateFormat クラスは、Javaが登場し、進化していく過程で、あまりにも急ぎすぎたのです。これらのクラスはうまく設計・実装されていませんでした。改善しようとした結果、あなたが見つけた非推奨となったのです。残念ながら、改善の試みはほとんど失敗しました。あなたは これらのクラスを避ける を完全に削除してください。これらはJava 8で新しいクラスによって取って代わられました。

あなたのコードの問題点

java.util.Dateは、日付と時刻の両方の部分を持っています。あなたのコードでは、時刻の部分が無視されています。そのため、Dateクラスは、JVMのデフォルトタイムゾーンによって定義された一日の始まりを取り、その時間をDateオブジェクトに適用します。だから、あなたのコードの結果は、それが実行されるマシンまたはどのタイムゾーンが設定されているかによって異なるでしょう。おそらく、あなたが望むものではありません。

誕生日など、時刻を除いた日付のみが必要な場合は、日付と時刻を表すために Date オブジェクトを作成します。日付の文字列だけを ISO 8601 の形式を使用します。 YYYY-MM-DD . または LocalDate オブジェクトをJoda-Timeから取得します(下記参照)。

Joda-Time(ジョダタイム

Javaで最初に学ぶべきこと。 面倒な java.util.Date & java.util.Calendar クラスを避ける。 Javaに同梱されている

で述べたように ユーザー3277382の回答 のどちらかを使用します。 ジョダタイム または新しい java.time.* パッケージ をJava 8に搭載した。

Joda-Time2.3のコード例

DateTimeZone timeZoneNorway = DateTimeZone.forID( "Europe/Oslo" );
DateTime birthDateTime_InNorway = new DateTime( 1985, 1, 1, 3, 2, 1, timeZoneNorway );

DateTimeZone timeZoneNewYork = DateTimeZone.forID( "America/New_York" );
DateTime birthDateTime_InNewYork = birthDateTime_InNorway.toDateTime( timeZoneNewYork ); 

DateTime birthDateTime_UtcGmt = birthDateTime_InNorway.toDateTime( DateTimeZone.UTC );

LocalDate birthDate = new LocalDate( 1985, 1, 1 );

コンソールにダンプする...

System.out.println( "birthDateTime_InNorway: " + birthDateTime_InNorway );
System.out.println( "birthDateTime_InNewYork: " + birthDateTime_InNewYork );
System.out.println( "birthDateTime_UtcGmt: " + birthDateTime_UtcGmt );
System.out.println( "birthDate: " + birthDate );

実行すると...

birthDateTime_InNorway: 1985-01-01T03:02:01.000+01:00
birthDateTime_InNewYork: 1984-12-31T21:02:01.000-05:00
birthDateTime_UtcGmt: 1985-01-01T02:02:01.000Z
birthDate: 1985-01-01

java.time(ジャバタイム

この場合 java.time とはほぼ同じです。 ジョダタイム .

タイムゾーンを取得する( ZoneId ) を作成し、そのタイムゾーンに割り当てられた日付-時間オブジェクトを構築します ( ZonedDateTime ). 次に 不変のオブジェクト パターンを使って、古いオブジェクトの同じインスタンス(Second)に基づいて新しいdate-timeを作成します。 エポック しかし、他のタイムゾーンが割り当てられています。最後に、私たちは LocalDate には時刻もタイムゾーンもありませんが、日付を決定する際にはタイムゾーンが適用されることに注意してください (新しい一日が早く明けるのは オスロ よりも ニューヨーク など)。

ZoneId zoneId_Norway = ZoneId.of( "Europe/Oslo" );
ZonedDateTime zdt_Norway = ZonedDateTime.of( 1985 , 1 , 1 , 3 , 2 , 1 , 0 , zoneId_Norway );

ZoneId zoneId_NewYork = ZonedId.of( "America/New_York" );
ZonedDateTime zdt_NewYork = zdt_Norway.withZoneSameInstant( zoneId_NewYork );

ZonedDateTime zdt_Utc = zdt_Norway.withZoneSameInstant( ZoneOffset.UTC );  // Or, next line is similar.
Instant instant = zdt_Norway.toInstant();  // Instant is always in UTC.

LocalDate localDate_Norway = zdt_Norway.toLocalDate();


について java.time(ジャバタイム

java.time フレームワークは、Java 8以降に組み込まれています。これらのクラスは、面倒な古い レガシー のような日付時間クラスがあります。 java.util.Date , Calendar , & SimpleDateFormat .

さらに詳しく知りたい方は オラクルチュートリアル . また、Stack Overflowで検索すると、多くの例や解説が見つかります。仕様書は JSR 310 .

ジョダタイム プロジェクトは、現在 メンテナンスモード への移行を推奨しています。 Java.time クラスがあります。

を交換することができます。 java.time オブジェクトを直接データベースとやり取りすることができます。データベースと直接接続するには JDBCドライバ に準拠した JDBC 4.2 またはそれ以降であること。文字列は必要ありません。 java.sql.* クラスがあります。Hibernate 5 & JPA 2.2サポート java.time .

java.timeクラスはどこで手に入りますか?