web-dev-qa-db-ja.com

java.time:CETタイムゾーンは夏時間を考慮していますか?

Java 8の新しいJava.time実装を使用し、UTCの [〜#〜] cet [〜#〜] 時間への出力について疑問に思います変換結果。

ZonedDateTime utcTime = ZonedDateTime.of(2014, 7, 1, 8, 0, 0, 0, ZoneId.of("UTC"));
ZonedDateTime cetTime = ZonedDateTime.ofInstant(utcTime.toInstant(), ZoneId.of("CET"));
System.out.println("Summer-UTC-Time: " + utcTime);
System.out.println("Summer-CET-Time: " + cetTime);

System.out.println();

utcTime = ZonedDateTime.of(2014, 1, 1, 8, 0, 0, 0, ZoneId.of("UTC"));
cetTime = ZonedDateTime.ofInstant(utcTime.toInstant(), ZoneId.of("CET"));
System.out.println("Winter-UTC-Time: " + utcTime);
System.out.println("Winter-CET-Time: " + cetTime);

CET時間は常にUTC時間の+1になると予想していましたが、代わりに次のようになりました。

Summer-UTC-Time: 2014-07-01T08:00Z[UTC]
Summer-CET-Time: 2014-07-01T10:00+02:00[CET] -> +2 **Unexpected**

Winter-UTC-Time: 2014-01-01T08:00Z[UTC]
Winter-CET-Time: 2014-01-01T09:00+01:00[CET] -> +1 Expected

そのため、CETを使用するときに予期していなかった夏時間に対処する必要があるようです。 Java.time CETは本当ですか [〜#〜] cest [〜#〜] ?はいの場合、CETが必要な場合、どのゾーンを使用する必要がありますか?

13
FrVaBe

CETのIANA定義 は、冬時間と夏時間の両方を含む中央ヨーロッパのタイムゾーンルールに従うことです。ルールを見ることができます ここ 、これは「CET」が夏の時間を含む "C-Eur" に基づいていることを示しています。

Java.timeルールの完全なセットも確認​​できます。

ZoneId zone = ZoneId.of("CET");
System.out.println(zone);
System.out.println(zone.getRules());
for (ZoneOffsetTransition trans : zone.getRules().getTransitions()) {
  System.out.println(trans);
}
for (ZoneOffsetTransitionRule rule : zone.getRules().getTransitionRules()) {
  System.out.println(rule);
}

印刷するもの:

CET
ZoneRules[currentStandardOffset=+01:00]
Transition[Gap at 1916-04-30T23:00+01:00 to +02:00]
Transition[Overlap at 1916-10-01T01:00+02:00 to +01:00]
Transition[Gap at 1917-04-16T02:00+01:00 to +02:00]
Transition[Overlap at 1917-09-17T03:00+02:00 to +01:00]
Transition[Gap at 1918-04-15T02:00+01:00 to +02:00]
Transition[Overlap at 1918-09-16T03:00+02:00 to +01:00]
Transition[Gap at 1940-04-01T02:00+01:00 to +02:00]
Transition[Overlap at 1942-11-02T03:00+02:00 to +01:00]
Transition[Gap at 1943-03-29T02:00+01:00 to +02:00]
Transition[Overlap at 1943-10-04T03:00+02:00 to +01:00]
Transition[Gap at 1944-04-03T02:00+01:00 to +02:00]
Transition[Overlap at 1944-10-02T03:00+02:00 to +01:00]
Transition[Gap at 1945-04-02T02:00+01:00 to +02:00]
Transition[Overlap at 1945-09-16T03:00+02:00 to +01:00]
Transition[Gap at 1977-04-03T02:00+01:00 to +02:00]
Transition[Overlap at 1977-09-25T03:00+02:00 to +01:00]
Transition[Gap at 1978-04-02T02:00+01:00 to +02:00]
Transition[Overlap at 1978-10-01T03:00+02:00 to +01:00]
Transition[Gap at 1979-04-01T02:00+01:00 to +02:00]
Transition[Overlap at 1979-09-30T03:00+02:00 to +01:00]
Transition[Gap at 1980-04-06T02:00+01:00 to +02:00]
Transition[Overlap at 1980-09-28T03:00+02:00 to +01:00]
Transition[Gap at 1981-03-29T02:00+01:00 to +02:00]
Transition[Overlap at 1981-09-27T03:00+02:00 to +01:00]
Transition[Gap at 1982-03-28T02:00+01:00 to +02:00]
Transition[Overlap at 1982-09-26T03:00+02:00 to +01:00]
Transition[Gap at 1983-03-27T02:00+01:00 to +02:00]
Transition[Overlap at 1983-09-25T03:00+02:00 to +01:00]
Transition[Gap at 1984-03-25T02:00+01:00 to +02:00]
Transition[Overlap at 1984-09-30T03:00+02:00 to +01:00]
Transition[Gap at 1985-03-31T02:00+01:00 to +02:00]
Transition[Overlap at 1985-09-29T03:00+02:00 to +01:00]
Transition[Gap at 1986-03-30T02:00+01:00 to +02:00]
Transition[Overlap at 1986-09-28T03:00+02:00 to +01:00]
Transition[Gap at 1987-03-29T02:00+01:00 to +02:00]
Transition[Overlap at 1987-09-27T03:00+02:00 to +01:00]
Transition[Gap at 1988-03-27T02:00+01:00 to +02:00]
Transition[Overlap at 1988-09-25T03:00+02:00 to +01:00]
Transition[Gap at 1989-03-26T02:00+01:00 to +02:00]
Transition[Overlap at 1989-09-24T03:00+02:00 to +01:00]
Transition[Gap at 1990-03-25T02:00+01:00 to +02:00]
Transition[Overlap at 1990-09-30T03:00+02:00 to +01:00]
Transition[Gap at 1991-03-31T02:00+01:00 to +02:00]
Transition[Overlap at 1991-09-29T03:00+02:00 to +01:00]
Transition[Gap at 1992-03-29T02:00+01:00 to +02:00]
Transition[Overlap at 1992-09-27T03:00+02:00 to +01:00]
Transition[Gap at 1993-03-28T02:00+01:00 to +02:00]
Transition[Overlap at 1993-09-26T03:00+02:00 to +01:00]
Transition[Gap at 1994-03-27T02:00+01:00 to +02:00]
Transition[Overlap at 1994-09-25T03:00+02:00 to +01:00]
Transition[Gap at 1995-03-26T02:00+01:00 to +02:00]
Transition[Overlap at 1995-09-24T03:00+02:00 to +01:00]
Transition[Gap at 1996-03-31T02:00+01:00 to +02:00]
Transition[Overlap at 1996-10-27T03:00+02:00 to +01:00]
Transition[Gap at 1997-03-30T02:00+01:00 to +02:00]
Transition[Overlap at 1997-10-26T03:00+02:00 to +01:00]
TransitionRule[Gap +01:00 to +02:00, SUNDAY on or after MARCH 25 at 02:00 STANDARD, standard offset +01:00]
TransitionRule[Overlap +02:00 to +01:00, SUNDAY on or after OCTOBER 25 at 02:00 STANDARD, standard offset +01:00]

ここで重要なのは、タイムゾーン識別子とその識別子の "short name" が2つの異なる要素であることを理解することです。識別子は常に「CET」に固定されていますが、名前は「CET」と「CEST」の間で変わります。

23
JodaStephen

オフセットがわかっていて、DTSを使用したくないので、ZoneOffset.ofHours(1)の代わりにZoneId.of("CET")メソッドを使用してみませんか?

また、任意のZoneIdインスタンスでnormalized()を呼び出して固定オフセットにすることもできますが、最初からオフセットを使用するよりも信頼性が低いように聞こえます。

From ZoneId javadoc

ZoneIdは、InstantとLocalDateTimeの間の変換に使用されるルールを識別するために使用されます。 IDには2つの異なるタイプがあります。

  • 固定オフセット-UTC /グリニッジからの完全に解決されたオフセット。すべてのローカル日時に同じオフセットを使用します
  • 地理的領域-UTC /グリニッジからのオフセットを見つけるための特定のルールセットが適用される領域

ほとんどの固定オフセットはZoneOffsetで表されます。任意のZoneIdでnormalized()を呼び出すと、固定オフセットIDがZoneOffsetとして表されるようになります。

固定オフセットを使用していない場合は、地理的地域を使用しています。つまり、DTSが監視されているかどうかは、地域によって異なります。PSTでも同じです。監視されていることがわかります。 DTS夏時間はPDTと呼ばれますが、混乱しますが、これがほとんどのツールの動作方法です。詳細については、 ZoneId javadoc をお読みください( Time-zone IDs セクション)。

1
akostadinov