あなたの結論は正しいです: offset-from-UTC からタイムゾーンを特定する信頼できる方法はありません。
のオフセットの例として、現在のリストに含まれる可能性のあるタイム ゾーンを約30 個-07:00
数えます: 、、および。America/Boise
America/Chihuahua
America/Edmonton
タイムゾーンは実際にはオフセットの集まりであり、その地域で一定期間使用された特定のオフセットを使用して経時的に行われた変更を記録し、その後別の一定期間にわたって変更されました。
たとえば、America/Los_Angeles
各年の一部には のオフセットが-08:00
あり、年の別の部分には があり-07:00
ます。そのため、そのタイム ゾーンは、年に少なくとも 2 つのオフセットの履歴を蓄積しています。対照的に、タイムゾーンを使用する隣接地域America/Phoenix
は、オフセットの変化を蓄積しておらず-07:00
、何十年も同じオフセットを保持しています。
したがって、オフセットとタイム ゾーンの間には多対多の関係があります。オフセットは、1 つ以上のタイム ゾーンで表示される場合があります。また、各タイム ゾーンには 1 つまたは複数のオフセットを設定できます (履歴によって変更されています)。
タイムゾーン名を含める
これが、java.time クラスの設計者が、オフセットのみを使用して標準のISO 8601形式を拡張し、タイム ゾーンの名前を角括弧で追加するZonedDateTime
自由をメソッドに持たせた理由です。toString
たとえば2007-12-03T10:15:30+01:00
、クラスは単に標準形式を生成するのではなく、 Europe/Paris2007-12-03T10:15:30+01:00[Europe/Paris]
というゾーンの名前を追加して生成します。
ZonedDateTime.now( ZoneId.of( "America/Montreal" ) )
.toString()
2007-12-03T10:15:30+01:00[ヨーロッパ/パリ]
タイムゾーン名を追加するというこの慣習が定着することを願っています。タイム ゾーン名の欠如は、ISO 8601 の設計において際立った仕事をした標準化委員会による驚くべき省略です。
ビジネス シナリオのコンテキストからの手がかりを使用して、タイム ゾーンを推測できます。しかし、私はそれに対して忠告します。特に世界中の政治家はタイムゾーンを頻繁に再定義する傾向があるため、推測は危険です.
UTC
日時値の格納、シリアル化、および交換のベスト プラクティスは、一般にUTCに調整することです。日時ライブラリのtzdataが最新であると仮定すると、UTC に調整すると、常に正確で明確な信頼できる値が得られます。
たとえば Java では、Instant
オブジェクトを使用または抽出することを意味します。このクラスは、 UTCInstant
のタイムライン上の瞬間をナノ秒単位(小数点以下 9 桁まで) で表します。
Instant instant = Instant.now();
…または…</p>
ZonedDateTime zdt = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );
Instant instant = zdt.toInstant();
このような値を表す標準の ISO 8601 形式の文字列は、UTCZ
の略で意味のある を使用します。Zulu
2007-12-03T09:15:30Z
OffsetDateTime
オフセットのみの日時を表す文字列が与えられた場合は、それをOffsetDateTime
オブジェクトとして解析します。
OffsetDateTime odt = OffsetDateTime.parse( "2007-12-03T10:15:30+01:00" );
odt.toString(): 2007-12-03T10:15:30+01:00
そこから、UTC の値を抽出できますInstant
。
Instant instant = odt.toInstant();
インスタント.toString(): 2007-12-03T09:15:30Z
または、目的のタイム ゾーンに調整して、オブジェクトと同じ瞬間を取得することもできZonedDateTime
ます。
ZoneId z = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = odt.atZoneSameInstant( z );
zdt.toString(): 2007-12-03T14:45:30+05:30[アジア/コルカタ]
用語: 「ローカル」</h1>
地域の特定の壁時計時間に調整された日付/時間を参照する場合は、「ローカル」という用語を避けることをお勧めします。java.time クラスやその他の文脈における「ローカル」という言葉は、特定の地域ではなく、任意の地域を意味します。ローカル日付/時間は、タイムライン上の特定の瞬間ではなく、考えられる瞬間の範囲についての大まかなアイデアにすぎません。
たとえば、今年のクリスマスの始まりのローカル日時は です2017-12-25T00:00:00
が、その真夜中の瞬間はコルカタよりもオークランドの方がはるかに早く、パリではさらに数時間遅く、モントリオールではさらに数時間遅くなります。
代わりに、特定のタイム ゾーンのレンズを通して見た特定の瞬間を意味する用語を使用することをお勧めしますzoned
。wall-clock time
ヒント: オフセット リテラル
質問は-7
、オフセットを参照するときにたまたま文字を使用していました。私はいつも提案します:
- ISO 8601 で要求されているように、パディング ゼロで 2 桁を使用する
- 一部のライブラリと形式で期待されるように、時間と分の両方を使用します。
-07:00
ではなく使用して-7
ください。