私は数年後にJavaプログラミングを学びます。私は、Java 8ではいくつかの新しい日付/時刻オブジェクトがあることに気付きました。Java 8 Beanの日付プロパティに使用するタイプ - InstantまたはZoneDateTime?
Java 8を使用する永続データBeanの場合、日付/時刻プロパティーにはどのようなタイプを使用する必要がありますか?それはInstant
、ZoneDateTime
またはDate
ですか?
私は数年後にJavaプログラミングを学びます。私は、Java 8ではいくつかの新しい日付/時刻オブジェクトがあることに気付きました。Java 8 Beanの日付プロパティに使用するタイプ - InstantまたはZoneDateTime?
Java 8を使用する永続データBeanの場合、日付/時刻プロパティーにはどのようなタイプを使用する必要がありますか?それはInstant
、ZoneDateTime
またはDate
ですか?
まず、古いクラス(Date
、Calendar
、SimpleDateFormat
)を避ける必要があります。彼らにはlots of problemsとdesign issuesがあり、そのほとんどは新しいAPIによって修正されています(新しいクラスが作成された理由です)。
IMO、UTCに日付/時刻オブジェクトを内部的に動作するように、常に良いでしょう - と、そのための最善のクラスUTCに常にある、Instant
です。だから、データベースに保存して内部操作を行うためには、UTCの日付/時刻を使用することを常に好みます。これは、混乱を少なくし、不必要な変換を避けるためです。ユーザーに、またはいくつかの他のインターフェイスに - -
場合は、この日付/時刻を表示する必要がある/
、あなたはそれが特定のタイムゾーンになりたいが、あなたはZonedDateTime
この
Instant
を変換します。
例:
// create current instant in UTC - Instant is **always** in UTC
Instant now = Instant.now();
System.out.println(now); // 2017-06-20T13:28:39.075Z
// converting to some timezone
ZonedDateTime z = now.atZone(ZoneId.of("America/Sao_Paulo"));
System.out.println(z); // 2017-06-20T10:28:39.075-03:00[America/Sao_Paulo]
// converting to another timezone
z = now.atZone(ZoneId.of("Europe/London"));
System.out.println(z); // 2017-06-20T14:28:39.075+01:00[Europe/London]
// converting back to Instant
System.out.println(z.toInstant()); // 2017-06-20T13:28:39.075Z
ので、UTCの瞬間は、サンパウロで2017-06-20T10:28:39.075-03:00
に対応2017-06-20T13:28:39.075Z
、およびロンドンの2017-06-20T14:28:39.075+01:00
(ZoneId
はすでに夏時間の変更の世話をすることに注意してください)です。
また、フルタイムゾーン名(America/Sao_Paulo
とEurope/London
)を使用しました。 Continent/City
という形式のこれらの名前は、IANA databaseで定義され、新しいAPIで使用されます。
ambiguous and not standardであるため、3文字のタイムゾーン名(ECT
またはCST
など)を使用しないでください。常にフルネームを使用する方が好きです。ZoneId.getAvailableZoneIds()
を呼び出すことで、利用可能なすべての名前を取得できます。
ZoneId.systemDefault()
を使用することもできます。これは、システムに設定されているデフォルトのタイムゾーンを取得します。しかし、これは実行時に変更される可能性があり、予測できない結果につながるので、明示的なタイムゾーンを使用する方が良いでしょう。
上記の出力は、各オブジェクトのtoString()
メソッドの結果です。
ZonedDateTime z = now.atZone(ZoneId.of("America/Sao_Paulo"));
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss xxx");
System.out.println(fmt.format(z)); // 20/06/2017 10:28:39 -03:00
すべての可能なフォーマットを参照してくださいjavadocを参照してください:あなたは別のフォーマットをしたい場合しかし、あなたはDateTimeFormatter
クラスを使用することができます。
考えられた答えに感謝します。タイムスタンプを元のエージェントのタイムゾーンに関連付ける方法に関するもう1つの関連する質問。私は注文を取るシステムを持っており、注文したエージェントのタイムゾーンを記録するにはどうすればよいのですか?「インスタント」を使って注文のタイムスタンプを保存したいとしますか?言い換えれば、彼らはサンパウロまたはロンドンにいたのですか? – user2868835
これが必須の場合、@ user2868835、 'ZoneId'を保存するか(' ZoneId.systemDefault() 'がJVMの設定を与えます)、例外を作成して、' Instant'の代わりに 'ZonedDateTime'を保存します。あなたに両方を与え、あなたはいつも必要に応じて変換することができます。 –
IMOの場合、 'Instant'を使って内部的に作業し、別のフィールドに' ZoneId'を格納する方が良いでしょう。(ユーザに日付を表示するときだけに 'atZone(zoneid)'を使います。 –
Beanのプロパティは、クライアントに提示する必要がある場合はいつでもInstant
であることが望ましいので、適切なZonedDateTime
に変換することができます。
Instant instant = Instant.now() ; // gives current instant of time in UTC.
//Can be converted to ZonedDateTime
ZoneId zone = ZoneId.of("Asia/Kolkata")) ;
ZonedDateTime zdt = instant.atZone(zone) ;
タイムゾーンを知る必要がある場合は、 'ZonedDateTime'を使用してください。特定の時点のみが必要な場合は、「即時」が優先されます。ご存知のように、あなたはいつでも 'ZonedDateTime'に変換して、あるタイムゾーンでそれをユーザに表示することができます。 –
古くなった 'Date'クラスを避ける方法があれば、そうしたいでしょう。私はそこに集まる。 「インスタント」は、一般的に、現代のそれに代わるものと考えられています。 –