Java 8でUTC + 0の日付を取得する方法


108

JavaのDateクラスに問題があります。日付クラスはローカルマシンの日付を返しますが、UTC-0が必要です。

私はググってJavaScriptには素晴らしい解決策を見つけましたが、Javaには何の役にも立ちません。

Java 8でUTC + 0の日付を取得する方法


12
java.util.Dateローカルマシンの日付ではありません。これは常に、UTC + 00:00を基準とした1970-01-01からの経過ミリ秒として定義されます。多分そのメソッドの振る舞いがtoString()あなたを混乱させ、どれが実際にローカルタイムゾーンの表現を使用しているのでしょう。
Meno Hochschild、2014年

:一つの可能性の答えは質問で見つけることができstackoverflow.com/questions/45350095/...
プリヤジャイナ

回答:


146

Java 8では、次のように記述できます。

OffsetDateTime utc = OffsetDateTime.now(ZoneOffset.UTC);

あなたのコメントに答えるために、あなたはそれを日付に変換することができます(あなたがレガシーコードに依存しない限り、私には理由がありません)またはエポック以来のミリ秒に変換できます:

Date date = Date.from(utc.toInstant());
long epochMillis = utc.toEpochSecond() * 1000;

1
ありがとう。ZonedDateTimeをDateまたはlong(ms)に変換することは可能ですか?
マーク

7
この回答のコードは、技術的に動作しますが、より多く使用することは適切ではありませんOffsetDateTimeではなく、ZonedDateTime私たちはオフセットUTC-からではなく、フルタイムゾーン単なるで作業していることを考えると?
バジルブルク

179

tl; dr

Instant.now()

java.time

Javaの初期バージョンにバンドルされていた厄介な古い日時クラスは、Java 8以降に組み込まれたjava.timeクラスに取って代わられました。Oracleチュートリアルを参照してください。機能の多くは、ThreeTen-BackportでJava 6および7にバックポートされ、さらにThreeTenABPで Androidに適応されています

Instant

アンは、Instantタイムライン上の瞬間表しUTCまでの解像度を持つナノ秒

Instant instant = Instant.now();

このtoStringメソッドは、標準のISO 8601形式のいずれかを使用して、日時値を表すテキストを含むStringオブジェクトを生成します。

String output = instant.toString();  

2016-06-27T19:15:25.864Z

このInstantクラスは、java.timeの基本的なビルディングブロッククラスです。これは、日時を処理する場合の必須クラスです。一般的に、UTCで日時の値を追跡、保存、交換することがベストプラクティスであるためです。

OffsetDateTime

ただしInstant、代替フォーマットで文字列を生成するためのフォーマットオプションがないなどの制限があります。柔軟性を高めるには、からInstantに変換しOffsetDateTimeます。UTCからオフセットを指定します。java.timeでは、これはZoneOffsetオブジェクトを意味します。ここでは、便利な定数を使用できるように、UTC(+00)を使い続けたいと考えていますZoneOffset.UTC

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );

2016-06-27T19:15:25.864Z

または、Instantクラスをスキップします。

OffsetDateTime.now( ZoneOffset.UTC )

今でOffsetDateTime手にオブジェクトは、使用することができますDateTimeFormatter別の形式でテキストをStringオブジェクトを作成します。を使用した多くの例については、スタックオーバーフローを検索してくださいDateTimeFormatter

ZonedDateTime

特定のタイムゾーンの実時間を表示する場合は、を適用してZoneIdを取得しZonedDateTimeます。

この例では、モントリオールのタイムゾーンを適用します。夏の夏時間(DST)の意味がない場合、ゾーンのオフセットはになり-04:00ます。したがって、出力で1519時刻が時間ではなく4時間早いことに注意してください。Instantそして、ZonedDateTimeの両方がちょうど2つの異なるレンズを通して見た、非常に同じ同時瞬間を表します。

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

2016-06-27T15:15:25.864-04:00 [アメリカ/モントリオール]

変換中

古い日時クラスを避ける必要がありますが、必要な場合は、古いクラスに追加された新しいメソッドを使用して変換できます。ここではjava.util.Date.from( Instant )and を使用していjava.util.Date::toInstantます。

java.util.Date utilDate = java.util.Date.from( instant );

そして、他の方向に行きます。

Instant instant= utilDate.toInstant();

同様に、との間で変換するためにGregorianCalendar(のサブクラスCalendar)に追加された新しいメソッドを探しますjava.time.ZonedDateTime

最新のjava.timeとレガシーの日時クラスのタイプの表。

java.timeについて

java.timeのフレームワークは、Java 8に組み込まれており、後にされています。これらのクラスは面倒古い取って代わるレガシーのような日付時刻クラスをjava.util.DateCalendar、& SimpleDateFormat

詳細については、Oracleチュートリアルを参照してください。また、スタックオーバーフローで多くの例と説明を検索してください。仕様はJSR 310です。

ジョダタイムプロジェクトは、今でメンテナンスモードへの移行をアドバイスjava.timeのクラス。

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

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


3
DSTは
ナンセンス

それで、DSTが存在しなかった場合ZonedDateTime、すべてZoneIdZoneOffset使用できる1つにマップするため、必要はありませんOffsetDateTime
wilmol

1
@wilmolいいえ。夏時間(DST)は、政治家がタイムゾーンの境界とそれらのゾーン内のオフセットを再定義することを選択する多くの理由の1つにすぎません。最近、北朝鮮は外交上の理由から韓国と同期するように30分時計を変更しました。戦争では、侵略者/占領者は、自国のオフセットと一致するようにオフセットを変更できます。現在、政府は夏時間の変更を中止することを選択しているが、以前の標準時間に戻すのではなく恒久的夏時間に留まっているという新しい流行があります。常にすべてのゾーン変更のオフセットを計画してください。そうしないと、アプリが最終的に壊れます。
バジルブルク

1
素晴らしい答え!あなたがこれに入れてくれた時間に本当に感謝しています。:)
drognisep

ZoneId.of( "America / Montreal"); なぜ誰かがjdkでそのようなことを発明するのですか?それは醜く、嫌で、実行時まで何か問題があるかどうかを知らず、誰がそれらのハードコードを覚えているでしょうか?ENUMクラスに実装しないのはなぜですか?
workplaylifecycle

4

java8では、InstantすでにUTCにあり、作業に便利なクラスを使用します。

import java.time.Instant;

Instant ins = Instant.now();
long ts = ins.toEpochMilli();

Instant ins2 = Instant.ofEpochMilli(ts)

または、以下を使用することもできます。

import java.time.*;

Instant ins = Instant.now(); 

OffsetDateTime odt = ins.atOffset(ZoneOffset.UTC);
ZonedDateTime zdt = ins.atZone(ZoneId.of("UTC"));

戻る Instant

Instant ins4 = Instant.from(odt);

3
いいえ、Instantありません現地時間。Instant定義上はUTCです。したがって、この回答に示されている陰謀がUTCに入ろうとする必要はありません。Instantすでにある UTCに。詳細とはるかに単純なコードについては、私の回答を参照しください。
バジルブルク

コメントをありがとう。
Abel Terefe


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.