45

UTC のタイムスタンプがあり、のような API 呼び出しを使用せずに現地時間に変換したいと考えていますTimeZone.getTimeZone("PST")。これをどのように正確に行うことになっていますか?私はあまり成功せずに次のコードを使用してきました:

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]

4

3 に答える 3

73

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

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

于 2012-09-19T01:12:56.190 に答える
22

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

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

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

  • Java 8 以降では、新しい API が組み込まれています。
  • Java 6 および 7では、新しいクラスのバックポートである ThreeTen Backportを取得します (これは、最新の API が最初に定義された JSR-310 の ThreeTen です)。
  • Android では、ThreeTen Backport の Android 版を使用します。これは ThreeTenABP と呼ばれ、この質問には素晴らしい説明があると思います: How to use ThreeTenABP in Android Project
于 2017-09-02T06:33:36.253 に答える