2017-06-20 2 views
2

私は数年後にJavaプログラミングを学びます。私は、Java 8ではいくつかの新しい日付/時刻オブジェクトがあることに気付きました。Java 8 Beanの日付プロパティに使用するタイプ - InstantまたはZoneDateTime?

Java 8を使用する永続データBeanの場合、日付/時刻プロパティーにはどのようなタイプを使用する必要がありますか?それはInstantZoneDateTimeまたはDateですか?

+0

タイムゾーンを知る必要がある場合は、 'ZonedDateTime'を使用してください。特定の時点のみが必要な場合は、「即時」が優先されます。ご存知のように、あなたはいつでも 'ZonedDateTime'に変換して、あるタイムゾーンでそれをユーザに表示することができます。 –

+0

古くなった 'Date'クラスを避ける方法があれば、そうしたいでしょう。私はそこに集まる。 「インスタント」は、一般的に、現代のそれに代わるものと考えられています。 –

答えて

1

まず、古いクラス(DateCalendarSimpleDateFormat)を避ける必要があります。彼らにはlots of problemsdesign 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:00ZoneIdはすでに夏時間の変更の世話をすることに注意してください)です。

また、フルタイムゾーン名(America/Sao_PauloEurope/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クラスを使用することができます。

+0

考えられた答えに感謝します。タイムスタンプを元のエージェントのタイムゾーンに関連付ける方法に関するもう1つの関連する質問。私は注文を取るシステムを持っており、注文したエージェントのタイムゾーンを記録するにはどうすればよいのですか?「インスタント」を使って注文のタイムスタンプを保存したいとしますか?言い換えれば、彼らはサンパウロまたはロンドンにいたのですか? – user2868835

+0

これが必須の場合、@ user2868835、 'ZoneId'を保存するか(' ZoneId.systemDefault() 'がJVMの設定を与えます)、例外を作成して、' Instant'の代わりに 'ZonedDateTime'を保存します。あなたに両方を与え、あなたはいつも必要に応じて変換することができます。 –

+0

IMOの場合、 'Instant'を使って内部的に作業し、別のフィールドに' ZoneId'を格納する方が良いでしょう。(ユーザに日付を表​​示するときだけに 'atZone(zoneid)'を使います。 –

1

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) ; 
関連する問題