web-dev-qa-db-ja.com

Java:UTCタイムスタンプを現地時間に変換するにはどうすればよいですか?

UTCのタイムスタンプがあり、TimeZone.getTimeZone("PST")などのAPI呼び出しを使用せずにローカル時間に変換したい。これをどのくらい正確に行う予定ですか?私は次のコードを使用していますが、あまり成功していません。

private static final SimpleDateFormat mSegmentStartTimeFormatter = new        SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");

Calendar calendar = Calendar.getInstance();

    try {
        calendar.setTime(mSegmentStartTimeFormatter.parse(startTime));
    }
    catch (ParseException e) {
        e.printStackTrace();
    }

    return calendar.getTimeInMillis();

サンプル入力値:[2012-08-15T22:56:02.038Z]

[2012-08-15T15:56:02.038Z]と同等のものを返す必要があります

30
Android Noob

Dateにはタイムゾーンがなく、内部的にUTCで保存されます。日付がフォーマットされている場合のみ、タイムゾーンの修正が適用されます。 DateFormatを使用する場合、デフォルトでは実行中のJVMのタイムゾーンになります。必要に応じてsetTimeZoneを使用して変更します。

DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));

Date date = utcFormat.parse("2012-08-15T22:56:02.038Z");

DateFormat pstFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
pstFormat.setTimeZone(TimeZone.getTimeZone("PST"));

System.out.println(pstFormat.format(date));

これは2012-08-15T15:56:02.038を出力します

UTCを示すため、PST形式の'Z'を省いたことに注意してください。 Zを使用した場合、出力は2012-08-15T15:56:02.038-0700になります

49
Steve Kuo

最新のJava日時APIを使用すると、これは簡単です。

    String inputValue = "2012-08-15T22:56:02.038Z";
    Instant timestamp = Instant.parse(inputValue);
    ZonedDateTime losAngelesTime = timestamp.atZone(ZoneId.of("America/Los_Angeles"));
    System.out.println(losAngelesTime);

これは印刷します

2012-08-15T15:56:02.038-07:00[America/Los_Angeles]

注意点:

  • あなたの期待に小さなバグがあります。タイムスタンプのZは、Zulu時間とも呼ばれるUTCを意味します。したがって、ローカル時間の値では、Zは存在しないはずです。オフセットはZではなく-7時間になっているため、たとえば2012-08-15T15:56:02.038-07:00のような戻り値が必要になります。
  • 3文字のタイムゾーンの略語は避けてください。それらは標準化されていないため、ほとんどの場合あいまいです。たとえば、PSTは、フィリピン標準時、太平洋標準時、またはピトケアン標準時を意味する場合があります(ただし、略語のSは夏時間(DSTを意味する)がよく使用されます)。太平洋標準時を意図した場合、それはタイムゾーンではありません。夏(サンプルタイムスタンプが該当する場所)では代わりに太平洋夏時間が使用されるためです。略語の代わりに、私のコードのようにregion/cityという形式のタイムゾーンIDを使用します。
  • 通常、タイムスタンプはInstantオブジェクトとして最も適切に処理されます。プレゼンテーションなど、必要な場合にのみZonedDateTimeに変換します。

質問:Javaバージョンで最新のAPIを使用できますか?

少なくともJava6を使用している場合、可能です。

  • Java 8以降では、新しいAPIが組み込まれています。
  • Java 6および7では、 ThreeTen Backport 、新しいクラスのバックポート(最新のAPIが最初に定義されたJSR-310のThreeTen)を取得します。
  • Androidでは、ThreeTen BackportのAndroidエディションを使用します。 ThreeTenABPと呼ばれ、 この質問:Android Project でThreeTenABPを使用する方法には素晴らしい説明があると思います。
13
Ole V.V.