web-dev-qa-db-ja.com

カレンダーからUTCタイムスタンプを取得するにはどうすればよいですか?

Javaを使用すると、Calendar.getInstance();を使用すると、現在のタイムゾーンのCalendarオブジェクトが取得されます。ただし、Java.sql.Timestampは通常、現地時間ではなくUTC時間で保存されます。では、カレンダーインスタンスからUTC時刻を取得するにはどうすればよいですか?

    DateFormat df = DateFormat.getTimeInstance();
    Calendar cal = Calendar.getInstance();
    Timestamp time = new Timestamp(cal.getTimeInMillis());

    // Prints local time
    System.out.println(df.format(new Date(time.getTime())));

    // Printe local time, but I want UTT Time
    System.out.println("timestamp: " + time);
13
Jonas

Calendar.getTime()を呼び出すと、関連するタイムゾーンを持たない値が得られます-または、インスタントカレンダーが表すこと。したがって、カレンダーのタイムゾーンで(たとえば)午前9時の場合、午後5時(UTC)になる可能性があります。

Java.util.Date(およびTimestamp)は、toString()を呼び出すと、システムのデフォルトのタイムゾーンでformattedになります(暗黙的にも明示的にも)-ただし、タイムゾーンがオブジェクト自体のデータの一部であると誤解させないでください。

正確に達成しようとしていることについて明確にする必要があります-そして、おそらくそれを見つけるでしょう Joda Time =組み込みライブラリよりも明確にコードでそれを表現できます。

16
Jon Skeet

あなたのコードはすでにあなたが望んでいることを正確に実行しています。 Timestamp(およびDate)にはタイムゾーン情報がなく、常にGMTタイムスタンプを含める必要があります(これはCalendar.getTimeInMillis()が返すものではありません)。

現地時間が表示されるのは、DateFormatファクトリメソッドとTimestamp.toString()が暗黙的にシステムのタイムゾーンを使用するためです。

11

tl; dr

Instant.now() 

従来の日時クラスを避ける

Java.timeクラスに取って代わった、厄介な古い日時クラスを使用しています。 DateFormatCalendar、またはTimestampを使用する必要はありません。

まだJava.timeに更新されていない古いコードの Calendar を使用する必要がある場合は、古いクラスに追加された新しいメソッドを使用して変換します。廃止されたJava.util.Dateを抽出し、Instantに変換します。

Instant instant = myCal.getTime().toInstant() ;

Java.timeの使用

現在の瞬間をInstantとして取得します。 Instant クラスは、タイムライン上の [〜#〜] utc [〜#〜] の瞬間を表し、 ナノ秒 (最大9(9 )小数の桁)。

Instant instant = Instant.now() ;

2017-02-17T03:29:15.725Z

データベース

JDBC 4.2以降では、Instantオブジェクトをデータベースと直接交換できます。そのため、廃止されたJava.sql.Timestampは必要ありません。

myPreparedStatement.setObject( … , instant ) ;

そして検索:

Instant instant = myResultSet.getObject( … , Instant.class ) ;

エポックから数える

エポック参照日1970-01-01T00:00:00Zからのミリ秒数が必要なようです。その数はInstantから抽出できます。ただし、Instantにはナノ秒の分解能があるため、データ損失に注意してください。これは、ミリ秒に切り捨てられます。

long millis = instant.toEpochMilli() ;

1487302155725


Java.timeについて

Java.time フレームワークはJava 8以降に組み込まれています。これらのクラスは、厄介な古い レガシーなどの日時クラスに取って代わります。 Java.util.DateCalendar 、& SimpleDateFormat

Joda-Time プロジェクトは、現在 メンテナンスモード で、 Java.time クラスへの移行を推奨しています。

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

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

ThreeTen-Extra プロジェクトは、追加のクラスでJava.timeを拡張します。このプロジェクトは、Java.timeに将来追加される可能性があることを証明する場です。 IntervalYearWeekYearQuartermore などの便利なクラスがここにあります。

3
Basil Bourque

次のスニペットはあなたの要件を満たすはずです:

df.setTimeZone(TimeZone.getTimeZone("UTC"));
2
Prashanth