SlideShare a Scribd company logo
.NET Framework における
タイムゾーンの取り扱い
Microsoft Corporation
Nobuyuki Akama
https://blogs.msdn.microsoft.com/nakama/ @nakama00
© 2018 Microsoft Corporation. All rights reserved.
本書の全部または一部の無断転載を禁じます。
p.2
時差情報の管理(タイムゾーン情報)
◼ 国際化アプリケーションで時刻を扱う場合には、時差に関す
る正しい取り扱いが必要になる
◼ 時差を考慮しながら時刻を正しく取り扱うためには、以下の
内容を理解する必要がある
 0. 時差とは何か
 1. 世界標準時(UTC)と地方標準時
 2. 夏時間の補正
 3. Windows OS におけるタイムゾーンの管理
 4. カルチャ情報とタイムゾーン情報の違い
◼ これらについて解説する
p.3
時差情報の管理(タイムゾーン情報)
-0. 時差とは何か
◼ 時差とは、地域ごとの経度の違いから来る時間の差
 一般に、各地域の時刻(時計)は、太陽の平均南中時刻が 12 時に
なるように定められている
 地球は反時計回りに自転しているため、太陽が南中する時刻が、地
球の場所ごとによってずれる
日本が最も
早く、南中を
迎える
イギリスは
日本より
遅れて南中
アメリカはさらに
それより遅れて
太陽が南中
日付変更線
(地球上で最も
早く太陽が南中
する場所)
2009/06/17
05:37:51
2009/06/16
21:37:51
2009/06/16
13:37:51
p.4
時差情報の管理(タイムゾーン情報)
-1. 世界標準時(UTC)と地方標準時
◼ こうした時差をうまく取り扱うために、世界標準時と地方標準
時が利用されている
 世界標準時(UTC/GMT、協定標準時/世界標準時)とは...
◼ 経度 0 度(イギリスのロンドンのグリニッジ天文台)での太陽の平均南中
時刻を正午とした時刻系 ※ これを GMT, グリニッジ標準時と呼ぶ
 地方標準時とは...
◼ 各国や地域(タイムゾーン)において定められた時刻
◼ 例えば、日本の場合は UTC に対して 9 時間早められた時計を使う、と
定められている
UTC / GMT (世界標準時)
(Coordinated Universal Time)
JST (日本標準時)
(Coordinated Universal Time)
2006/05/05 00:00:00 GMT 2006/05/05 09:00:00 JST
JST = UTC+09:00
と書く
※ UTC と GMT は厳密には
異なるが、実質的には同じ
ものだと考えて差し支えない
p.5
時差情報の管理(タイムゾーン情報)
-1. 世界標準時(UTC)と地方標準時
◼ 時刻を表す際は「どの地域の時刻か」を付記する必要がある
 正しい時刻の書き方について
◼ 単純に "2006/05/05 00:00:00" と記述すると、それが世界標準時なの
か、地方標準時なのかが分からなくなる
◼ このため、通常は日時の末尾に 3 文字のアルファベット文字を付与し、
それがどの地方標準時でのものなのかを明示する
 世界標準時と地方標準時との変換について
◼ 地方標準時と世界標準時とのずれは UTC±XX:XX の形式で書かれる
◼ これを元に、世界標準時と地方標準時を変換すればよい
◼ 例) JST での時刻 = UTC での時刻 + 09:00
地方標準時 UTC とのずれ 具体例
イギリス GMT (グリニッジ標準時) UTC+00:00 2006/05/05 00:00:00 GMT
日本 JST (日本標準時) UTC+09:00 2006/05/05 09:00:00 JST
アメリカ西海岸(冬場) PST (太平洋標準時) UTC-08:00 2006/05/04 16:00:00 PST
p.6
具体例 利用している国・地域 方角
GMT/UTC-12:00 -12:00 (12時間遅れている) JST+03:00 -21:00 (21時間遅れている) 2006/05/03 01:27:00 ベイカー島 西側
GMT/UTC-11:00 -11:00 (11時間遅れている) JST+04:00 -20:00 (20時間遅れている) 2006/05/03 02:27:00 ミッドウェー島、サモア
GMT/UTC-10:00 -10:00 (10時間遅れている) JST+05:00 -19:00 (19時間遅れている) 2006/05/03 03:27:00 ハワイ
GMT/UTC-09:00 -09:00 (9時間遅れている) JST+06:00 -18:00 (18時間遅れている) 2006/05/03 04:27:00 アラスカ
GMT/UTC-08:00 -08:00 (8時間遅れている) JST+07:00 -17:00 (17時間遅れている) 2006/05/03 05:27:00 アメリカ太平洋時間 (米国およびカナダ)、ティファナ
GMT/UTC-07:00 -07:00 (7時間遅れている) JST+08:00 -16:00 (16時間遅れている) 2006/05/03 06:27:00 アメリカ山地時間 (米国およびカナダ)、アリゾナ、チワワ、ラパス、
マサトラン
GMT/UTC-06:00 -06:00 (6時間遅れている) JST+09:00 -15:00 (15時間遅れている) 2006/05/03 07:27:00 アメリカ中部時間 (米国およびカナダ), メキシコシティ、モンテレー、
サスカチュワン、中央アメリカ
GMT/UTC-05:00 -05:00 (5時間遅れている) JST+10:00 -14:00 (14時間遅れている) 2006/05/03 08:27:00 アメリカ東部時間 (米国およびカナダ)、インディアナ東部、ボゴタ、
リマ、キト
GMT/UTC-04:00 -04:00 (4時間遅れている) JST+11:00 -13:00 (13時間遅れている) 2006/05/03 09:27:00 大西洋標準時(カナダ)、カラカス、サンティアゴ、ラパス
GMT/UTC-03:30 -03:30 (3.5時間遅れている) JST+11:30 -12:30 (12.5時間遅れている) 2006/05/03 09:57:00 ニューファンドランド
GMT/UTC-03:00 -03:00 (3時間遅れている) JST-12:00 -12:00 (12時間遅れている) 2006/05/03 10:27:00 グリーンランド、ブレノスアイレス、ジュージタウン、ブラジリア
GMT/UTC-02:00 -02:00 (2時間遅れている) JST-11:00 -11:00 (11時間遅れている) 2006/05/03 11:27:00 中央大西洋
GMT/UTC-01:00 -01:00 (1時間遅れている) JST-10:00 -10:00 (10時間遅れている) 2006/05/03 12:27:00 カーボベルデ諸島、アゾレス諸島
GMT/UTC (基準) JST-09:00 -09:00 (9時間遅れている) 2006/05/03 13:27:00 カサブランカ、モンロビア、ダブリン、エジンバラ、リスボン、ロンドン
(グリニッジ標準時)
GMT/UTC+01:00 +01:00 (1時間進んでいる) JST-08:00 -08:00 (8時間遅れている) 2006/05/03 14:27:00 アムステルダム、ベルリン、ベルン、ローマ、ストックホルム、ウィー
ン、サラエボ、スコピエ、ワルシャワ、ザグレブ、ブリュッセル、コペン
ハーゲン、マドリード、パリ、ベオグラード、プラチスラバ、ブダペス
ト、リュブリャナ、プラハ、西中央アフリカ
GMT/UTC+02:00 +02:00 (2時間進んでいる) JST-07:00 -07:00 (7時間遅れている) 2006/05/03 15:27:00 アテネ、ベイルート、イスタンブール、ミンスク、エルサレム、カイロ、
ハラーレ、プレトリア、ブカレスト、ヘルシンキ、キエフ、リガ、ソフィ
ア、タリン、ビリニュス
GMT/UTC+03:00 +03:00 (3時間進んでいる) JST-06:00 -06:00 (6時間遅れている) 2006/05/03 16:27:00 クウェート、リヤド、ナイロビ、バグダッド、モスクワ、サンクトペテル
スブルグ、ボルゴグラード
GMT/UTC+03:30 +03:00 (3.5時間進んでいる) JST-05:30 -05:30 (5.5時間遅れている) 2006/05/03 16:57:00 テヘラン
GMT/UTC+04:00 +04:00 (4時間進んでいる) JST-05:00 -05:00 (5時間遅れている) 2006/05/03 17:27:00 アブダビ、マスカット、バク、トビリシ、エレバン
GMT/UTC+04:30 +04:30 (4.5時間進んでいる) JST-04:30 -04:30 (4.5時間遅れている) 2006/05/03 16:57:00 カブール
GMT/UTC+05:00 +05:00 (5時間進んでいる) JST-04:00 -04:00 (4時間遅れている) 2006/05/03 18:27:00 イスラマバード、カラチ、タシケント、エカテリンバーグ
GMT/UTC+05:30 +05:30 (5.5時間進んでいる) JST-03:30 -03:30 (3.5時間遅れている) 2006/05/03 18:57:00 チェンナイ、コルカタ、ムンバイ、ニューデリー
GMT/UTC+05:45 +05:45 (5.75時間進んでいる) JST-03:15 -03:15 (3.25時間遅れている) 2006/05/03 19:12:00 カトマンズ
GMT/UTC+06:00 +06:00 (6時間進んでいる) JST-03:00 -03:00 (3時間遅れている) 2006/05/03 19:27:00 ダッカ、アスタナ、アルマティ、ノボシビルスク、スリ・ジャヤワルダナ
GMT/UTC+06:30 +06:30 (6.5時間進んでいる) JST-02:30 -02:30 (2.5時間遅れている) 2006/05/03 19:57:00 ラングーン
GMT/UTC+07:00 +07:00 (7時間進んでいる) JST-02:00 -02:00 (2時間遅れている) 2006/05/03 20:27:00 クラスノヤルスク、バンコク、ハノイ、ジャカルタ
GMT/UTC+08:00 +08:00 (8時間進んでいる) JST-01:00 -01:00 (1時間遅れている) 2006/05/03 21:27:00 イルクーツク、ウランバートル、クアラルンプール、シンガポール、
パース、台北、北京、長慶、香港、ウルムチ
GMT/UTC+09:00 +09:00 (9時間進んでいる) JST (基準) 2006/05/03 22:27:00 ソフル、ヤクーツク、大阪、札幌、東京
GMT/UTC+09:30 +09:30 (9.5時間進んでいる) JST+00:30 +00:30 (.5時間進んでいる) 2006/05/03 22:57:00 アデレード、ダーウィン
GMT/UTC+10:00 +10:00 (10時間進んでいる) JST+01:00 +01:00 (1時間進んでいる) 2006/05/03 23:27:00 ウラジオストク、キャンベラ、メルボルン、シドニー、グアム、ポートモ
レスビー、ブリスベン、ホバート
GMT/UTC+11:00 +11:00 (11時間進んでいる) JST+02:00 +02:00 (2時間進んでいる) 2006/05/04 00:27:00 マガダン、ソロモン諸島、ニューカレドニア
GMT/UTC+12:00 +12:00 (12時間進んでいる) JST+03:00 +03:00 (3時間進んでいる) 2006/05/04 01:27:00 オークランド、ウェリントン、フィジー、カムチャッカ、マーシャル諸島
GMT/UTC+13:00 +13:00 (13時間進んでいる) JST+04:00 +04:00 (4時間進んでいる) 2006/05/04 02:27:00 トンガ、ヌクアロファ
GMT/UTC+14:00 +14:00 (14時間進んでいる) JST+05:00 +05:00 (5時間進んでいる) 2006/05/04 03:27:00 キリバス(クリスマス島) 東側
UTCに対する時差 日本に対する時差
代表的なタイムゾーン(※ サマータイム未考慮)
夏時間を意識しない
場合の日時
※ 「遅れている」「進んでいる」と
時刻の加減算の関係に注意
p.7
時差情報の管理(タイムゾーン情報)
-1. 世界標準時(UTC)と地方標準時
◼ 世界標準時と地方標準時とのずれをオフセット値と呼ぶ
 (GMT 以外の)JST, EST などは国際的に定められた表記ではない
 このため、オフセット値を使って表記するのが正しい記述方法
◼ 例) 以下の表記はすべて「同一の日時」を指す
 時差を考慮すると、すべて同じ時刻(瞬間)を表現していることになる
UTC / GMT
(世界標準時)
UTC = UTC + 00:00
JST
(日本標準時)
JST = UTC + 09:00
2007/11/20 15:32:10 +09:00
PST
(太平洋標準時)
PST = UTC - 08:00
2007/11/20 15:32:10 JST
2007/11/20 06:32:10 +00:00
2007/11/20 06:32:10 GMT
2007/11/19 22:32:10 -08:00
2007/11/19 22:32:10 PST
=
=
=
=
オフセット値
(UTC に対するずれ)
p.8
時差情報の管理(タイムゾーン情報)
-1. 世界標準時(UTC)と地方標準時
◼ (当たり前だが)異なるタイムゾーンの時刻データ同士を差し
引きしても、正しい時間は算出できない
 いったん UTC に変換すれば、正しい時間が算出できる
 具体例) 成田 2009/01/03 15:00 発 ロサンゼルス 2009/01/03
09:00 着の飛行機のフライト時間は?
いったん
UTC に
変換
2009/01/03
09:00 PST
2009/01/03
15:00 JST
イギリス 成田
ロサン
ゼルス
01/03
06:00 UTC
01/03
15:00 JST
01/03
17:00 UTC
01/03
09:00 PST
11 時間のフライト
p.9
時差情報の管理(タイムゾーン情報)
-1. 世界標準時(UTC)と地方標準時
◼ 同じ国の中に複数のタイムゾーンがあるケースがあることに
も注意する
 具体例) アメリカの場合
◼ 本土だけでも EST, CST, MST, PST の 4 つのタイムゾーンがある
◼ 同様に、ロシアの場合には、国内に 10 個のタイムゾーンがある
 同一の国 = 同一のタイムゾーンとは限らないことに注意する
タイムゾーン名 略称 オフセット 主な都市
東海岸標準時 Eastern Standard Time EST UTC - 05:00 ニューヨーク、ワシントン、ボストン
中西部標準時 Central Standard Time CST UTC - 06:00 シカゴ、ヒューストン、ダラス
山岳部標準時 Mountain Standard Time MST UTC - 07:00 フェニックス、デンバー
太平洋標準時 Pacific Standard Time PST UTC - 08:00 ロサンゼルス、ラスベガス、シアトル
p.10
時差情報の管理(タイムゾーン情報)
-2. 夏時間の補正
◼ 夏時間(サマータイム, Daylight Saving Time)とは、夏場の
時計を一定時間遅らせるものである
 夏場の日没時刻を見かけ上遅らせて、経済活動を活性化させる
 具体例) アメリカ太平洋側の標準時(PST, 太平洋標準時)の場合
◼ 4 月第一日曜午前 2 時から 10 月最終日曜の午前 2 時が 1 時間シフト
◼ システム的には、タイムゾーンが変更されたとして取り扱われる
 PST (太平洋標準時) = UTC-08:00
 PDT (太平洋夏時間) = UTC-07:00
2006/01/01
00:00:00
2006/12/31
12:59:59
2006/04/02
02:00:00
PDT
(太平洋夏時間)
2006/04/02
03:00:00
2006/10/29
02:00:00
2006/10/29
01:00:00
DaylightTime.Start DaylightTime.End
DaylightTime.Delta
夏時間
オフセット値が
変化する!
PST
(太平洋標準時)
p.11
1 時間
スキップする
PDT に変更
(UTC-07:00)
PST
(UTC-08:00)
PST に変更
(UTC-08:00)
PDT
(UTC-07:00)
1 時間
巻き戻る
Windows XP の場合
※ Windows Vista 以降の OS では、
タイムゾーン表記が直接的に変わる
様子を見ることができなくなってしま
ったが、内部動作は同じ
p.12
時差情報の管理(タイムゾーン情報)
-2. 夏時間の補正
◼ 夏時間は、政治的な理由によって決定されるものである
 サマータイムの開始・終了日時、ずらす時間は国によって異なり、さら
に年次や法律改正などによって変更される
 Windows OS の場合、サマータイムの情報はタイムゾーン情報と併
せてレジストリで管理されている
◼ Vista 以降の OS では、自動的にデータが更新されるようになっている
(Dynamic DST(Daylight Saving Time) 機能)
◼ XP, 2003 などでは Windows Update による更新が必要
導入国 開始日時 終了日時 デルタ 注記
アメリカ 3月最終日曜日1時 10月最終日曜日2時 1時間 2007年以降は期間変更
ヨーロッパ 3月最終日曜日1時 10月最終日曜日1時 1時間
ロシア 3月最終日曜日2時 10月最終日曜日3時 1時間
オーストラリア 10月最終日曜日2時 翌年3月最終日曜日3時 1時間
ニュージーランド 10月最終日曜日2時 翌年3月最終日曜日3時 1時間
ブラジル 10月第3日曜日0時 翌年2月第3日曜日0時 1時間
日本 5月第1土曜日24時 9月第2土曜日24時 1時間 1952年に廃止
p.13
時差情報の管理(タイムゾーン情報)
-2. 夏時間の補正
◼ 同一のタイムゾーンであっても、夏時間がある場合には、単
純な時刻の加減算処理を行ってはならない!
 具体例) アメリカ太平洋側における、以下の 2 つの日時の差は?
◼ 2006/04/02 01:00 (冬時間)
◼ 2006/04/02 05:00 (夏時間)
 このような場合も、いったん UTC に変換してから計算するとラク
いったん
UTC に
変換
2009/01/03
09:00 PST
2009/01/03
15:00 JST
3 時間差
イギリス
アメリカ太平
洋冬時間
アメリカ太平
洋夏時間
UTC
PST = UTC -
08:00
PDT = UTC -
07:00
2006/04/02
09:00 UTC
2006/04/02
01:00 PST
2006/04/02
12:00 UTC
2006/04/02
05:00 PDT
見かけは 4 時間差だが...
p.14
時差情報の管理(タイムゾーン情報)
-3. Windows OS におけるタイムゾーンの管理
◼ Windows OS では、これらのタイムゾーン情報がレジストリ
で管理されている
 エンドユーザは、自分が属するタイムゾーンを選択することになる
 これにより、指定したタイムゾーンに関するオフセット情報が利用され
るようになる コンピュータの
タイムゾーン設定
レジストリのタイムゾーン情報
(HKEY_LOCAL_MACHINE¥SOFTWARE
¥Microsoft¥Windows NT¥CurrentVersion
¥TimeZones)
※ 直接いじってはいけない
設定したタイムゾーンで
日時が表示される
p.15
時差情報の管理(タイムゾーン情報)
-3. Windows OS におけるタイムゾーンの管理
◼ (参考) Windows OS におけるタイムゾーンの管理方法
 OS が管理しているタイムゾーンは約 80 種類
 表示名(DisplayName), 地方標準時名(StandardName), 夏時間
名(Daylight Name)は OS の言語により変化するので注意する
タイムゾーン識別
ID
UTC に対す
る時差(お
セット)
表示名 地方標準時名
夏時間
有無
夏時間名
GMT Standard
Time
+00:00:00
(GMT) グリニッジ標準時: ダブリン、エ
ジンバラ、リスボン、ロンドン
GMT 標準時 True GMT 夏時間
Tokyo Standard
Time
+09:00:00 (GMT+09:00) 大阪、札幌、東京 東京 (標準時) False -
Atlantic Standard
Time
-04:00:00 (GMT-04:00) 大西洋標準時 (カナダ) 大西洋標準時 True 大西洋夏時間
Eastern Standard
Time
-05:00:00
(GMT-05:00) 東部標準時 (米国および
カナダ)
東部標準時 True 東部夏時間
Central Standard
Time
-06:00:00
(GMT-06:00) 中部標準時 (米国および
カナダ)
中部標準時 True 中部夏時間
Pacific Standard
Time
-08:00:00
(GMT-08:00) 太平洋標準時 (米国およ
びカナダ)
太平洋標準時 True 太平洋夏時間
この部分は
OS の言語に依存しない
p.16
時差情報の管理(タイムゾーン情報)
-3. Windows OS におけるタイムゾーンの管理
タイムゾーン識別 ID UTC に対する時差 表示名 地方標準時名 夏時間有無 夏時間名
Id BaseUtcOffset DisplayName StandardName SupportsDaylightSavingTime DaylightName
Greenwich Standard Time 00:00:00
(GMT) カサブランカ、モンロビア、レイキャビ
ク
グリニッジ標準時 False グリニッジ夏時間
GMT Standard Time 00:00:00
(GMT) グリニッジ標準時: ダブリン、エジンバ
ラ、リスボン、ロンドン
GMT 標準時 True GMT 夏時間
W. Europe Standard Time 01:00:00
(GMT+01:00) アムステルダム、ベルリン、ベ
ルン、ローマ、ストックホルム、ウィーン
西ヨーロッパ標準時 True 西ヨーロッパ夏時間
Central European Standard Time 01:00:00
(GMT+01:00) サラエボ、スコピエ、ワルシャ
ワ、ザグレブ
中央ヨーロピアン標準時 True 中央ヨーロピアン夏時間
Romance Standard Time 01:00:00
(GMT+01:00) ブリュッセル、コペンハーゲ
ン、マドリード、パリ
ロマンス標準時 True ロマンス夏時間
Central Europe Standard Time 01:00:00
(GMT+01:00) ベオグラード、ブラチスラバ、
ブダペスト、リュブリャナ、プラハ
中央ヨーロッパ標準時 True 中央ヨーロッパ夏時間
W. Central Africa Standard Time 01:00:00 (GMT+01:00) 西中央アフリカ 西中央アフリカ標準時 False 西中央アフリカ夏時間
GTB Standard Time 02:00:00
(GMT+02:00) アテネ、ブカレスト、イスタン
ブール
GTB 標準時 True GTB 夏時間
Jordan Standard Time 02:00:00 (GMT+02:00) アンマン ヨルダン標準時 True ヨルダン夏時間
Namibia Standard Time 02:00:00 (GMT+02:00) ウィントフック ナミビア標準時 True ナミビア夏時間
Israel Standard Time 02:00:00 (GMT+02:00) エルサレム エルサレム標準時 True エルサレム夏時間
Egypt Standard Time 02:00:00 (GMT+02:00) カイロ エジプト標準時 True エジプト夏時間
South Africa Standard Time 02:00:00 (GMT+02:00) ハラーレ、プレトリア 南アフリカ標準時 False 南アフリカ夏時間
FLE Standard Time 02:00:00
(GMT+02:00) ヘルシンキ、キエフ、リガ、ソ
フィア、タリン、ビリニュス
FLE 標準時 True FLE 夏時間
Middle East Standard Time 02:00:00 (GMT+02:00) ベイルート 中東標準時 True 中東夏時間
E. Europe Standard Time 02:00:00 (GMT+02:00) ミンスク 東ヨーロッパ標準時 True 東ヨーロッパ夏時間
Arab Standard Time 03:00:00 (GMT+03:00) クウェート、リヤド アラブ標準時 False アラブ夏時間
Georgian Standard Time 03:00:00 (GMT+03:00) トビリシ グルジア標準時 False グルジア夏時間
E. Africa Standard Time 03:00:00 (GMT+03:00) ナイロビ 東アフリカ標準時 False 東アフリカ夏時間
Arabic Standard Time 03:00:00 (GMT+03:00) バグダッド アラビック標準時 True アラビック夏時間
(参考) Windows OS のタイムゾーン情報一覧 1/5
p.17
時差情報の管理(タイムゾーン情報)
-3. Windows OS におけるタイムゾーンの管理
タイムゾーン識別 ID UTC に対する時差 表示名 地方標準時名 夏時間有無 夏時間名
Id BaseUtcOffset DisplayName StandardName SupportsDaylightSavingTime DaylightName
Russian Standard Time 03:00:00
(GMT+03:00) モスクワ、サンクト ペテルスブ
ルグ、ボルゴグラード
ロシア標準時 True ロシア夏時間
Iran Standard Time 03:30:00 (GMT+03:30) テヘラン イラン標準時 True イラン夏時間
Arabian Standard Time 04:00:00 (GMT+04:00) アブダビ、マスカット アラビア標準時 False アラビア夏時間
Armenian Standard Time 04:00:00 (GMT+04:00) エレバン アルメニア標準時 True アルメニア夏時間
Caucasus Standard Time 04:00:00 (GMT+04:00) コーカサス標準時 コーカサス標準時 False コーカサス夏時間
Azerbaijan Standard Time 04:00:00 (GMT+04:00) バク アゼルバイジャン標準時 True アゼルバイジャン夏時間
Afghanistan Standard Time 04:30:00 (GMT+04:30) カブール アフガニスタン標準時 False アフガニスタン夏時間
West Asia Standard Time 05:00:00
(GMT+05:00) イスラマバード、カラチ、タシケ
ント
西アジア標準時 False 西アジア夏時間
Ekaterinburg Standard Time 05:00:00 (GMT+05:00) エカテリンバーグ エカテリンバーグ標準時 True エカテリンバーグ夏時間
Sri Lanka Standard Time 05:30:00 (GMT+05:30) スリ・ジャヤワルダナプラ スリランカ標準時 False スリランカ夏時間
India Standard Time 05:30:00
(GMT+05:30) チェンナイ、コルカタ、ムンバ
イ、ニューデリー
インド標準時 False インド夏時間
Nepal Standard Time 05:45:00 (GMT+05:45) カトマンズ ネパール標準時 False ネパール夏時間
Central Asia Standard Time 06:00:00 (GMT+06:00) アスタナ、ダッカ 中央アジア標準時 False 中央アジア夏時間
N. Central Asia Standard Time 06:00:00 (GMT+06:00) アルマティ、ノボシビルスク 中央アジア北標準時 True 中央アジア北夏時間
Myanmar Standard Time 06:30:00 (GMT+06:30) ヤンゴン (ラングーン) ミャンマー標準時 False ミャンマー夏時間
North Asia Standard Time 07:00:00 (GMT+07:00) クラスノヤルスク 北アジア標準時 True 北アジア夏時間
SE Asia Standard Time 07:00:00 (GMT+07:00) バンコク、ハノイ、ジャカルタ 東南アジア標準時 False 東南アジア夏時間
North Asia East Standard Time 08:00:00 (GMT+08:00) イルクーツク、ウランバートル 北アジア東標準時 True 北アジア東夏時間
Singapore Standard Time 08:00:00
(GMT+08:00) クアラルンプール、シンガポー
ル
マレー半島標準時 False マレー半島夏時間
W. Australia Standard Time 08:00:00 (GMT+08:00) パース 西オーストラリア標準時 True 西オーストラリア夏時間
(参考) Windows OS のタイムゾーン情報一覧 2/5
p.18
時差情報の管理(タイムゾーン情報)
-3. Windows OS におけるタイムゾーンの管理
タイムゾーン識別 ID UTC に対する時差 表示名 地方標準時名 夏時間有無 夏時間名
Id BaseUtcOffset DisplayName StandardName SupportsDaylightSavingTime DaylightName
China Standard Time 08:00:00 (GMT+08:00) 北京、重慶、香港、ウルムチ 中国 (標準時) False 中国 (夏時間)
Taipei Standard Time 08:00:00 (GMT+08:00) 台北 台北 (標準時) False 台北 (夏時間)
Korea Standard Time 09:00:00 (GMT+09:00) ソウル 韓国 (標準時) False 韓国 (夏時間)
Yakutsk Standard Time 09:00:00 (GMT+09:00) ヤクーツク ヤクーツク標準時 True ヤクーツク夏時間
Tokyo Standard Time 09:00:00 (GMT+09:00) 大阪、札幌、東京 東京 (標準時) False 東京 (夏時間)
Cen. Australia Standard Time 09:30:00 (GMT+09:30) アデレード 中央オーストラリア標準時 True 中央オーストラリア夏時間
AUS Central Standard Time 09:30:00 (GMT+09:30) ダーウィン AUS 中央標準時 False AUS 中央夏時間
Vladivostok Standard Time 10:00:00 (GMT+10:00) ウラジオストク ウラジオストク標準時 True ウラジオストク夏時間
AUS Eastern Standard Time 10:00:00
(GMT+10:00) キャンベラ、メルボルン、シド
ニー
AUS 東部標準時 True AUS 東部夏時間
West Pacific Standard Time 10:00:00 (GMT+10:00) グアム、ポートモレスビー 西太平洋 (標準時) False 西太平洋 (夏時間)
E. Australia Standard Time 10:00:00 (GMT+10:00) ブリスベン 東オーストラリア標準時 False 東オーストラリア夏時間
Tasmania Standard Time 10:00:00 (GMT+10:00) ホバート タスマニア標準時 True タスマニア夏時間
Central Pacific Standard Time 11:00:00
(GMT+11:00) マガダン、ソロモン諸島、
ニューカレドニア
中央太平洋 (標準時) False 中央太平洋 (夏時間)
New Zealand Standard Time 12:00:00 (GMT+12:00) オークランド、ウェリントン ニュージーランド標準時 True ニュージーランド夏時間
Fiji Standard Time 12:00:00
(GMT+12:00) フィジー、カムチャツカ、マー
シャル諸島
フィジー標準時 False フィジー夏時間
Tonga Standard Time 13:00:00 (GMT+13:00) ヌクアロファ トンガ標準時 False トンガ夏時間
Azores Standard Time -01:00:00 (GMT-01:00) アゾレス諸島 アゾレス諸島標準時 True アゾレス諸島夏時間
Cape Verde Standard Time -01:00:00 (GMT-01:00) カーボベルデ諸島 カーボベルデ標準時 False カーボベルデ夏時間
Mid-Atlantic Standard Time -02:00:00 (GMT-02:00) 中央大西洋 中央大西洋標準時 True 中央大西洋夏時間
Greenland Standard Time -03:00:00 (GMT-03:00) グリーンランド グリーンランド標準時 True グリーンランド夏時間
(参考) Windows OS のタイムゾーン情報一覧 3/5
p.19
時差情報の管理(タイムゾーン情報)
-3. Windows OS におけるタイムゾーンの管理
タイムゾーン識別 ID UTC に対する時差 表示名 地方標準時名 夏時間有無 夏時間名
Id BaseUtcOffset DisplayName StandardName SupportsDaylightSavingTime DaylightName
SA Eastern Standard Time -03:00:00
(GMT-03:00) ブエノスアイレス、ジョージタウ
ン
SA 東部標準時 False SA 東部夏時間
E. South America Standard Time -03:00:00 (GMT-03:00) ブラジリア 南アメリカ東部標準時 True 南アメリカ東部夏時間
Montevideo Standard Time -03:00:00 (GMT-03:00) モンテビデオ モンテビデオ標準時 True モンテビデオ夏時間
Newfoundland Standard Time -03:30:00 (GMT-03:30) ニューファンドランド ニューファンドランド標準時 True ニューファンドランド夏時間
SA Western Standard Time -04:00:00 (GMT-04:00) カラカス、ラパス 南アメリカ西部標準時 False 南アメリカ西部夏時間
Pacific SA Standard Time -04:00:00 (GMT-04:00) サンティアゴ 太平洋南アメリカ標準時 True 太平洋南アメリカ夏時間
Central Brazilian Standard Time -04:00:00 (GMT-04:00) マナウス 中央ブラジル標準時 True 中央ブラジル夏時間
Atlantic Standard Time -04:00:00 (GMT-04:00) 大西洋標準時 (カナダ) 大西洋標準時 True 大西洋夏時間
US Eastern Standard Time -05:00:00 (GMT-05:00) インディアナ東部 米国 東部標準時 False 米国 東部夏時間
SA Pacific Standard Time -05:00:00
(GMT-05:00) ボゴタ、リマ、キト、リオ ブラン
コ
南アメリカ太平洋標準時 False 南アメリカ太平洋夏時間
Eastern Standard Time -05:00:00
(GMT-05:00) 東部標準時 (米国およびカナ
ダ)
東部標準時 True 東部夏時間
Central Standard Time (Mexico) -06:00:00
(GMT-06:00) グアダラハラ、メキシコシティ、
モンテレー - 新
中部標準時 (メキシコ) True 中部夏時間 (メキシコ)
Mexico Standard Time -06:00:00
(GMT-06:00) グアダラハラ、メキシコシティ、
モンテレー - 旧
メキシコ標準時 True メキシコ夏時間
Canada Central Standard Time -06:00:00 (GMT-06:00) サスカチュワン カナダ中部標準時 False カナダ中部夏時間
Central America Standard Time -06:00:00 (GMT-06:00) 中央アメリカ 中央アメリカ標準時 False 中央アメリカ夏時間
Central Standard Time -06:00:00
(GMT-06:00) 中部標準時 (米国およびカナ
ダ)
中部標準時 True 中部夏時間
US Mountain Standard Time -07:00:00 (GMT-07:00) アリゾナ 米国 山地標準時 False 米国 山地夏時間
Mountain Standard Time (Mexico) -07:00:00
(GMT-07:00) チワワ、ラパス、マサトラン -
新
山地標準時 (メキシコ) True 山地夏時間 (メキシコ)
Mexico Standard Time 2 -07:00:00
(GMT-07:00) チワワ、ラパス、マサトラン -
旧
メキシコ 山地標準時 2 True メキシコ 山地夏時間 2
Mountain Standard Time -07:00:00
(GMT-07:00) 山地標準時 (米国およびカナ
ダ)
山地標準時 True 山地夏時間
(参考) Windows OS のタイムゾーン情報一覧 4/5
p.20
時差情報の管理(タイムゾーン情報)
-3. Windows OS におけるタイムゾーンの管理
◼ (参考) レジストリでのデータ管理について
 JST, EST, PST, PDT などの表記は OS やレジストリでは管理され
ていない(これらは通称であり正式表記ではないため)
 Dymamic DST 機能は XP, 2003 でも条件付きで利用可能
◼ 更新プログラムの適用に加えて、.NET Fx 3.5 のライブラリを利用する
 詳細は以下の blog を参照
◼ Exploring Windows Time Zones with System.TimeZoneInfo
◼ http://blogs.msdn.com/bclteam/archive/2007/06/07/exploring-
windows-time-zones-with-system-timezoneinfo-josh-free.aspx
タイムゾーン識別 ID UTC に対する時差 表示名 地方標準時名 夏時間有無 夏時間名
Id BaseUtcOffset DisplayName StandardName SupportsDaylightSavingTime DaylightName
Pacific Standard Time (Mexico) -08:00:00 (GMT-08:00) ティファナ、バハカリフォルニア 太平洋標準時 (メキシコ) True 太平洋夏時間 (メキシコ)
Pacific Standard Time -08:00:00
(GMT-08:00) 太平洋標準時 (米国およびカ
ナダ)
太平洋標準時 True 太平洋夏時間
Alaskan Standard Time -09:00:00 (GMT-09:00) アラスカ アラスカ標準時 True アラスカ夏時間
Hawaiian Standard Time -10:00:00 (GMT-10:00) ハワイ ハワイ標準時 False ハワイ夏時間
Samoa Standard Time -11:00:00 (GMT-11:00) ミッドウェー島、サモア サモア標準時 False サモア夏時間
Dateline Standard Time -12:00:00 (GMT-12:00) 国際日付変更線 西側 日付変更線 (標準時) False 日付変更線 (夏時間)
(参考) Windows OS のタイムゾーン情報一覧 5/5
p.21
時差情報の管理(タイムゾーン情報)
-4. カルチャ情報とタイムゾーン情報の違い
◼ 時刻データを取り扱う場合には、以下の 2 つの点に注意す
る必要がある
 ① カルチャとタイムゾーンの両方を同時に考える必要がある
◼ すべての日時データは、UTC 化すれば同一のものとして扱える
◼ これをローカライズする際は、カルチャとタイムゾーンの両方を意識する
必要がある
 ② メッセージではなくデータのカルチャを考える必要がある
◼ 特定の日時をどの言語で表示するのかは、メッセージのカルチャではな
くデータのカルチャにより決定する必要がある
◼ これらについて解説する
p.22
時差情報の管理(タイムゾーン情報)
-4. カルチャ情報とタイムゾーン情報の違い
◼ ① カルチャとタイムゾーンの両方を同時に考える必要がある
 通貨や質量などのデータ値と異なり、日時データは、UTC に変換す
れば、全世界のデータを共通に取り扱うことができる
◼ このため、日時データの加減算処理などを行う場合には、UTC に変換し
ておけば間違いがなかった
◼ データベースに保存する際も、UTC に変換してから保存すれば、夏時間
であるか否かといったことを記述する必要もない
 例) 単純に "2006/10/29 01:30" とだけ記述すると、冬時間なのか夏時間な
のかがわからなくなってしまう!
 しかし、UTC ベースで保存された値を表示する際には、タイムゾーン
とカルチャの両方を考える必要が生じる
◼ まず、タイムゾーンを意識して、UTC で保存された時刻をローカル時刻
に変換する
◼ 次に、その時刻を、現地のカルチャに従った方法で表示する必要がある
 具体例 → 次ページ
p.23
◼ 具体例) UTC 保存された日時データを正しく表示する方法
 まずタイムゾーン変換をした後で、各カルチャで表示する
2007/11/20
06:32:10 (UTC)
2007/11/19
22:32:10 (PST)
2007/11/20
15:32:10 (JST)
時差情報の管理(タイムゾーン情報)
-4. カルチャ情報とタイムゾーン情報の違い
JST に変換
PST に変換
decimal = 100m; decimal = 100m;
Tuesday, November 20,
2007 10:32:10 PM
2007年11月20日
15:32:10
ja-jp で表示 en-us で表示
$100.00¥100
p.24
時差情報の管理(タイムゾーン情報)
-4. カルチャ情報とタイムゾーン情報の違い
◼ ② メッセージではなくデータのカルチャを考える必要がある
 特定の日時データをどの言語で表示するのかは、メッセージのカル
チャではなくデータのカルチャによって決定される
◼ 具体例) "2007/11/20 15:32:10" というデータを表示する場合
 データ値のカルチャが ja-jp の場合 → "2007 年 11 月 20 日 15:32:10"
 メッセージのカルチャを en-us に変えても、データ値のカルチャが ja-jp の場
合には、日本語表示 "2007 年 11 月 20 日 15:32:10" になってしまう
◼ 具体例) Windows Vista のカレンダー
 メッセージのカルチャ(=ユーザ UI 言語)を変更しても変わらない
 データ値のカルチャ(=ユーザロケール)を変更すると切り替わる
英語 日本語 アラビア語
p.25
時差情報の管理(タイムゾーン情報)
-4. カルチャ情報とタイムゾーン情報の違い
◼ ② (続き)
 OS のユーザロケール(データ値のカルチャ)を変更すると、
◼ データ値の文字列化表示形式が変わり、カレンダー表示も変わる
◼ その他の表示はすべて日本語(=ユーザ UI 言語の設定)のまま
英語のカレンダーに
変わる!
(他はすべて日本語)
p.26
時差情報の管理(タイムゾーン情報)
-4. カルチャ情報とタイムゾーン情報の違い
◼ ② (続き)
 日付表記やカレンダー表示が、メッセージのカルチャではなくデータ
のカルチャによって設定されるのは、以下のような理由による
◼ 「ある瞬間」(日時)をどのように解釈して表示するのかは、カルチャに
よって変化する(=単なる言葉の違いだけではない)
 1 週間は何日か?(※ 現在は全世界で七曜が使われている)
 1 週間は何曜日始まりか?
 各曜日の意味は?(※ 日曜日が休み、月曜日始まりとは限らない)
 現地歴カレンダーとしては何が使われているか?(和暦など)
 etc.
 このため、日付表記やカレンダー表示の方式は、メッセージのカル
チャではなくデータ値のカルチャによって設定しなければならない
◼ 直感と異なるため、十分に注意すること!
p.27
時差情報の管理(タイムゾーン情報)
-4. カルチャ情報とタイムゾーン情報の違い
◼ ② (続き)
 前述の事項は、外国人が PC を利用する際に制約になることがある
◼ 例) 日本に在住
しているアメリカ
人の場合
英語版 OS
ユーザロケール = ja-JP
ユーザ UI 言語 = en-USアメリカ人
日本でお金を扱ったりする場合は
「ドル」ではなく「円」であるため、
ユーザロケールは変更する
ユーザロケールを
反映するため、
カレンダーは
日本語表記になる
OS の表示はユーザ UI
言語を反映するため、
英語表記になる
p.28
時差情報の管理(タイムゾーン情報)
-まとめ
◼ 国際化アプリケーションで時刻を扱う場合には、時差に関す
る正しい取り扱いが必要になる
◼ キーポイントとしては以下の通り
 同一の国・場所だからといって、タイムゾーンが共通とは限らない(特
に夏時間の存在に注意!)
 アプリケーション内部では、地方標準時を UTC ベースに変換して、
オフセット情報と共に取り扱うと安全である
 Windows OS は、タイムゾーン情報をレジストリで管理している
 UTC ベースで保存された日時データを表示する際は、タイムゾーン
情報を基にオフセット変換したあと、カルチャに合わせた表示を行う
 時刻の表示形式は、データ値のカルチャによって決定される
.NET Framework 上での
時差の取り扱いに関する注意点
p.30
時差の取り扱い方
◼ .NET Framework での時差の取り扱い機能は、バージョン
アップとともに強化されてきた
 特に .NET Framework 3.5 では、時差やタイムゾーンを直接操作で
きるライブラリが追加された
 バージョンごとに利用可能な機能が異なるため、これらの 3 つのライ
ブラリについて、利用方法と利用上の注意点を解説する
DateTime DateTimeOffset TimeZoneInfo
.NET Fx 1.0/1.1 △ 制限あり × 利用不可 × 利用不可
.NET Fx 2.0 ◎ × 利用不可 × 利用不可
.NET Fx 3.0 ◎ × 利用不可 × 利用不可
.NET Fx 3.5 ◎ ◎ ◎
A. で解説 B. で解説 C. で解説
p.31
時差の取り扱い方
◼ A. DateTime 型による日時の取り扱い
 DateTime 型は、世界標準時(UTC)と地方標準時(Local)の取り扱
いが曖昧である
◼ 特に重要なのは、DateTime 型はデータが UTC/Local のどちらである
かの情報は持つが、オフセット情報は持っていないという点である
◼ このため、十分注意して処理を記述しないと、計算ミスや時刻変換ミスを
することになる
 DateTime 型で日時を取り扱う場合には、以下の点に注意する必要
がある
◼ i. 地方標準時(Local)と世界標準時(UTC)間の時刻変換
◼ ii. 加減算処理に関する挙動
◼ iii. ToString() メソッドの挙動
◼ iv. Parse(), ParseExact() メソッドの挙動
p.32
時差の取り扱い方
◼ A. DateTime 型による日時の取り扱い(続き)
 i. 地方標準時(Local)と世界標準時(UTC)間の時刻変換
◼ DateTime 型には、当該コンピュータに設定されたタイムゾーンの地方標
準時と、世界標準時(UTC)間の変換を行う機能が備わっている
 .ToLocalTime() メソッド、.ToUniversalTime() メソッドにより変換する
 注意: 任意のタイムゾーン間の時差補正を行う機能は備わっていない
◼ DateTime 型には、当該データが世界標準時、地方標準時のどちらであ
るのかを示すフラグが備わっている
 Kind プロパティ : Local, Utc, Unspecified(後述) の 3 つ
 これにより、当該 DateTime データが、地方標準時のものなのか、世界標準
時のものなのかが明確化されるようになっている
 このため、上記の時差補正メソッドを複数回呼び出しても、正しいデータ変換
が行われる (※ .NET Fx 2.0 の新機能)
◼ 具体的なコード例 → 次ページ
p.33
// ※ 以下の処理結果は、すべてタイムゾーンが JST の PC 上で行った場合のもの
// パターン① JST ベースの時刻を扱う場合
DateTime date1 = DateTime.Now; // 地方標準時による現在時刻を取得
Console.WriteLine(date1.Kind); // Local (地方標準時によるデータ)
Console.WriteLine(date1); // 2006/05/05 20:44:37
Console.WriteLine(date1.ToLocalTime()); // 2006/05/05 20:44:37
Console.WriteLine(date1.ToUniversalTime()); // 2006/05/05 11:44:37
// パターン② UTC ベースの時刻を扱う場合
DateTime date2 = DateTime.UtcNow; // 世界標準時による現在時刻を取得
Console.WriteLine(date2.Kind); // Utc (世界標準時によるデータ)
Console.WriteLine(date2); // 2006/05/05 11:44:37
Console.WriteLine(date2.ToLocalTime()); // 2006/05/05 20:44:37
Console.WriteLine(date2.ToUniversalTime()); // 2006/05/05 11:44:37
// パターン③ JST ベースの時刻を UTC ベースに変換してから扱う場合
DateTime date3 = date1.ToUniversalTime(); // 地方標準時を世界標準時に変換
Console.WriteLine(date3.Kind); // Utc (世界標準時によるデータ)
Console.WriteLine(date3); // 2006/05/05 11:44:37
Console.WriteLine(date3.ToLocalTime()); // 2006/05/05 20:44:37
Console.WriteLine(date3.ToUniversalTime()); // 2006/05/05 11:44:37
C#
JST → JST では
変化しない
UTC → UTC では
変化しない
p.34
時差の取り扱い方
◼ A. DateTime 型による日時の取り扱い(続き)
 ii. 加減算処理に関する挙動
◼ DateTime 型は、そのデータがどのタイムゾーンに属するのか(=オフ
セット値はいくつなのか)の情報を持たない
 このため、加減算を地方標準時ベースで行うと誤った結果になる恐れがある
◼ 以下のパターンでの加減算処理は、正しい答えを返さない
 ① 異なるタイムゾーンで表現された DateTime 値同士の加減算
 ② 夏時間が存在するタイムゾーンの DateTime 値同士の加減算
※ 同一タイムゾーンでも、夏時間変更またがりの 2 つの DateTime は、異な
るオフセット値を持つことに注意!
◼ 正しい加減算を行うためには、UTC ベースで処理を行う
 いったん UTC ベースの時刻に変換した上で、加減算処理を行う
◼ 具体例 → 次ページ参照
p.35
時差の取り扱い方
// 具体例:夏時間補正タイミングにまたがった減算処理
DateTime date1 = DateTime.Now; // 地方標準時を取得
// 2006/10/29 01:59:49 PDT
Console.WriteLine(date1); // 2006/10/29 01:59:49
Console.WriteLine(date1.IsDaylightSavingTime()); // True (夏時間)
Console.WriteLine(date1.Kind); // Local (地方標準時)
Console.WriteLine(date1.ToString("zzz")); // -07:00 ← PDT = UTC-07:00
Console.ReadLine();
DateTime date2 = DateTime.Now; // 夏時間終了後の地方標準時を取得
// 2006/10/29 01:00:08 PST
Console.WriteLine(date2); // 2006/10/29 01:00:08
Console.WriteLine(date2.IsDaylightSavingTime()); // False (夏時間)
Console.WriteLine(date2.Kind); // Local (地方標準時)
Console.WriteLine(date2.ToString("zzz")); // -08:00 ← PST = UTC-08:00
// × 地方標準時ベースで計算すると、間違った答えになる
TimeSpan span1 = date2.Subtract(date1); // ローカル時刻同士を差し引き
Console.WriteLine(span1.TotalSeconds); // × -3581 sec (≒-00:59:41)
// ◎ UTC ベースで計算すると、正しい答えになる
TimeSpan span2 = date2.ToUniversalTime().Subtract(date1.ToUniversalTime());
// いったんUTCに変換してから差し引き
Console.WriteLine(span2.TotalSeconds); // ◎ +19 sec
C#
OS のタイムゾーン設定
=PST/PDT (太平洋標準時)
の場合
p.36
時差の取り扱い方
// 具体例:夏時間補正タイミングにまたがった加算処理
// 夏時間が終了する直前の時刻に対して、5 分後の時刻を計算
DateTime date1 = DateTime.Now; // 地方標準時を取得
// 2006/10/29 01:59:49 PDT
Console.WriteLine(date1); // 2006/10/29 01:59:49
Console.WriteLine(date1.IsDaylightSavingTime()); // True
Console.WriteLine(date1.Kind); // Local
Console.WriteLine(date1.ToString("zzz")); // -07:00
// × 地方標準時ベースで加算すると間違った答えになる
DateTime date2 = date1.AddMinutes(5); // × 2006/10/29 02:04:49 PST
Console.WriteLine(date2); // 2006/10/29 02:04:49
Console.WriteLine(date2.IsDaylightSavingTime()); // False
Console.WriteLine(date2.Kind); // Local
Console.WriteLine(date2.ToString("zzz")); // -08:00 ←PST=UTC-08:00
// ◎ UTC ベースで加算すると正しい答えになる
DateTime date3 = date1.ToUniversalTime().AddMinutes(5).ToLocalTime();
// ◎ 2006/10/29 01:04:49 PST
Console.WriteLine(date3); // 2006/10/29 01:04:49
Console.WriteLine(date3.IsDaylightSavingTime()); // False
Console.WriteLine(date3.Kind); // Local
Console.WriteLine(date3.ToString("zzz")); // -08:00 ←PST=UTC-08:00
C#
OS のタイムゾーン設定
=PST/PDT (太平洋標準時)
の場合
p.37
時差の取り扱い方
◼ A. DateTime 型による日時の取り扱い(続き)
 iii. ToString() メソッドの挙動
◼ .ToString() メソッドは世界標準時と地方標準時のどちらであるのかを一
切考慮しないため、アプリ側の配慮が必要になる
 具体例) "r" (RFC1123)の場合 → Local 時刻であっても GMT 表記になる
 具体例) "zzz" (タイムゾーンオフセット)の場合 → Utc 時刻であっても当該
PC のタイムゾーンオフセットを表示してしまう
// ※ 正しい時刻は以下の通り
// Fri, 05 May 2006 21:09:36 JST または 2006/05/05 21:09:36 (JST)
// Fri, 05 May 2006 12:09:36 UTC または 2006/05/05 12:09:36 (UTC)
// パターン① JST による時刻を扱う場合
DateTime date1 = DateTime.Now; // JST での現在時刻
Console.WriteLine(date1.ToString("r")); // × Fri, 05 May 2006 21:09:36 GMT
Console.WriteLine(date1.ToString("yyyy/MM/dd HH:mm:ss (UTCzzz)")); // ◎ 2006/05/05 21:09:36 (UTC+09:00)
// パターン② UTC による時刻を扱う場合
DateTime date2 = DateTime.UtcNow; // UTC での現在時刻
Console.WriteLine(date2.ToString("r")); // ◎ Fri, 05 May 2006 12:09:36 GMT
Console.WriteLine(date2.ToString("yyyy/MM/dd HH:mm:ss (UTCzzz)")); // × 2006/05/05 12:09:36 (UTC+09:00)
C#
Local 時刻に対しては
"r" や "R" を使ってはならない
(UTC 変換してから使う)
p.38
時差の取り扱い方
◼ A. DateTime 型による日時の取り扱い(続き)
 iv. Parse(), ParseExact() メソッドの挙動
◼ .Parse(), .ParseExact() やコンストラクタで作成した日時は、世界標準
時・地方標準時のどちらであるかが不明なデータとして扱われる
◼ .ToUniversalTime() などを呼び出す際に不適切な計算をする恐れがあ
るため、パース時に明示的に Local / Utc 設定を行うとよい
// 特に指定をせずにコンストラクタやParse() 処理を行うと、Unspecified 扱いになる
DateTime date1 = new DateTime(2006, 5, 4, 21, 19, 15);
Console.WriteLine(date1); // 2006/05/04 21:19:15
Console.WriteLine(date1.ToUniversalTime()); // 2006/05/04 12:19:15
// ※ date1 が JST ベースと解釈された上で UTC に変換される
Console.WriteLine(date1.ToLocalTime()); // 2006/05/05 06:19:15
// ※ date1 が UTC ベースと解釈された上で JST に変換される
// Local/Utc どちらであるかを明示するためには、SpecifyKind() 命令を利用する
DateTime date2 = DateTime.ParseExact("2006/05/04 21:19:15", "yyyy/MM/dd HH:mm:ss",
DateTimeFormatInfo.InvariantInfo);
DateTime.SpecifyKind(date2, DateTimeKind.Utc);
// コンストラクタを使う場合には、パラメータとして明示的な指定ができる
DateTime date3 = new DateTime(2006, 5, 4, 21, 19, 15, DateTimeKind.Utc);
C#
当該データが Local/Utc の
どちらであるのかを明示する
p.39
時差の取り扱い方
◼ A. DateTime 型による日時の取り扱い(続き)
 まとめると、以下の通りとなる
◼ DateTime 型には、オフセット値を保持する機能がない
 地方標準時か、世界標準時かを判定する機能しかない
 このため、オフセット値については開発者側で意識する必要がある
◼ DateTime 型の時差補正は、PC のオフセット値を元にして計算される
 その DateTime 値の「本当のオフセット値」を意識した変換は行わない
◼ DateTime 型の加減算処理を行う際は、必ず UTC を介して行う
 DateTime 型は、「見た目の数値」をそのまま加減算処理する
 たとえ同一タイムゾーンであったとしても、夏時間前後でオフセット値が変化
する恐れがあるため、必ず UTC を介して計算する
◼ ToString(), Parse(), ParseExact() 処理は、タイムゾーンやオフセット値
を一切考慮してくれない
 内部に Kind フラグを持っているにもかかわらず、これらを無視して挙動する
 このため、タイムゾーンやオフセットについては開発者側で注意する
p.40
時差の取り扱い方
◼ B. DateTimeOffset 型による日時の取り扱い
 前述したような複雑な問題を解決するため、.NET Framework 3.5 で
は「オフセット値も内部に保持できる」日時型が用意された
◼ DateTime 型 → 「地方標準時か否か」のフラグしか持てない
◼ DateTimeOffset 型 → 「オフセット値」を直接保持できる
 オフセット値を直接保持できるため、前述したような問題はほとんど
発生しなくなる!
// DateTime 型の場合
DateTime tokyo1 = DateTime.Now;
Console.WriteLine(tokyo1); // ◎ 2007/11/20 15:09:45
Console.WriteLine(tokyo1.ToString("r")); // × Tue, 20 Nov 2007 15:09:45 GMT
// DateTimeOffset 型の場合
DateTimeOffset tokyo2 = DateTimeOffset.Now;
Console.WriteLine(tokyo2); // ◎ 2007/11/20 15:09:45 +09:00
Console.WriteLine(tokyo2.ToString("r")); // ◎ Tue, 20 Nov 2007 06:09:45 GMT
C#
フォーマットは GMT 表記だが
値は地方標準時のまま
オフセット情報が自動的につき、
GMT 表記すると自動変換される
p.41
時差の取り扱い方
◼ B. DateTimeOffset 型による日時の取り扱い(続き)
 具体例) 夏時刻補正タイミングまたがりでの加減算処理
// 具体例:夏時間補正タイミングにまたがった減算処理
DateTimeOffset date1 = DateTimeOffset.Now; // 地方標準時を取得
Console.WriteLine(date1); // 2006/10/29 01:59:49 -07:00
Console.WriteLine(date1.ToUniversalTime()); // 2006/10/29 08:59:49 +00:00
Console.ReadLine();
DateTimeOffset date2 = DateTimeOffset.Now; // 夏時間終了後の地方標準時を取得
Console.WriteLine(date2); // 2006/10/29 01:00:08 -08:00
Console.WriteLine(date2.ToUniversalTime()); // 2006/10/29 09:00:08 +00:00
// ◎ 地方標準時ベースで計算しても、正しい答えを返す
TimeSpan span1 = date2.Subtract(date1); // ローカル時刻同士を差し引き
Console.WriteLine(span1.TotalSeconds); // ◎ +19 sec
C#
OS のタイムゾーン設定
=PST/PDT (太平洋標準時)
の場合
p.42
時差の取り扱い方
◼ B. DateTimeOffset 型による日時の取り扱い(続き)
 具体例) .ToString() メソッドの振る舞い
◼ DateTimeOffset.Now や .UtcNow によるデータ取得時に、自動的にオ
フセット情報も取り込まれる
◼ このため、"r" フォーマットや "zzz" フォーマットを利用した場合でも、適切
なデータを表示することができるようになっている
// ※ 正しい時刻は以下の通り
// Tue, 21 Nov 2006 16:56:51 JST または Tue, 21 Nov 2006 16:56:51 (+09:00)
// Tue, 21 Nov 2006 07:56:51 UTC または Tue, 21 Nov 2006 07:56:51 (+00:00)
// パターン① JST による時刻を扱う場合
DateTimeOffset date1 = DateTimeOffset.Now; // JST での現在時刻
Console.WriteLine(date1.ToString("r")); // ◎ Tue, 21 Nov 2006 07:56:51 GMT
Console.WriteLine(date1.ToString("yyyy/MM/dd HH:mm:ss (UTCzzz)")); // ◎ 2006/11/21 16:56:51 (UTC+09:00)
// パターン② UTC による時刻を扱う場合
DateTimeOffset date2 = DateTimeOffset.UtcNow; // UTC での現在時刻
Console.WriteLine(date2.ToString("r")); // ◎ Tue, 21 Nov 2006 07:56:51 GMT
Console.WriteLine(date2.ToString("yyyy/MM/dd HH:mm:ss (UTCzzz)")); // ◎ 2006/11/21 07:56:51 (UTC+00:00)
C#
すべて正しい!
p.43
時差の取り扱い方
◼ B. DateTimeOffset 型による日時の取り扱い(続き)
 具体例) .Parse() メソッドやコンストラクタの振る舞い
◼ DateTimeOffset 型は、オフセット情報を内部に保持する必要があるた
め、データ作成時には必ずオフセット情報が必要になる
DateTimeOffset date1 = new DateTimeOffset(2006, 5, 4, 21, 19, 15, TimeSpan.FromHours(9));
Console.WriteLine(date1); // 2006/05/04 21:19:15 +09:00
Console.WriteLine(date1.ToUniversalTime()); // 2006/05/04 12:19:15 +00:00
Console.WriteLine(date1.ToLocalTime()); // 2006/05/05 06:19:15 +09:00
// オフセット情報つき文字列を解析する (存在しない場合はローカル PC のオフセット値が利用される)
DateTimeOffset date2 = DateTimeOffset.ParseExact("2006/05/04 21:19:15 +09:00", "yyyy/MM/dd HH:mm:ss zzz",
DateTimeFormatInfo.InvariantInfo);
Console.WriteLine(date2); // 2006/05/04 21:19:15 +09:00
// オフセットを後から指定する場合には、DateTime 型を経由するとよい
DateTime temp = DateTime.ParseExact("2006/05/04 21:19:15", "yyyy/MM/dd HH:mm:ss",
DateTimeFormatInfo.InvariantInfo);
DateTimeOffset date3 = new DateTimeOffset(temp, TimeSpan.FromHours(-8));
Console.WriteLine(date3); // 2006/05/04 21:19:15 -08:00
Console.WriteLine(date3.ToUniversalTime()); // 2006/05/04 05:19:15 +00:00
C#
オフセット値を明示
p.44
時差の取り扱い方
◼ C. タイムゾーン間の時差補正
 DateTime 型や DateTimeOffset 型だけでは、世界標準時(UTC)と
の間の変換しか行えない
 任意のタイムゾーン間での時差補正を行うためには、.NET
Framework 3.5 で導入された TimeZoneInfo クラスを利用する
◼ Windows OS のレジストリに格納されたタイムゾーン情報(80 個前後の
タイムゾーン情報)を元に、タイムゾーン間の時刻変換を実施できる
※ (注意) 時差補正用データは、OS 側に依存していることに注意する
(.NET Framework 内部にデータを持っているわけではない!)
p.45
時差の取り扱い方
DateTime tokyo = DateTime.Now; // 2007/11/20 14:06:09 (JST)
DateTime utc = tokyo.ToUniversalTime(); // 2007/11/20 05:06:09 (UTC)
// 東部標準時 (EST) への変換
TimeZoneInfo estTZ = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
TimeZoneInfo tokyoTZ = TimeZoneInfo.Local;
// 変換方法① : UTC 経由で変換する場合
DateTime est1 = TimeZoneInfo.ConvertTimeFromUtc(utc, estTZ);
// 変換方法② : 直接変換する場合
DateTime est2 = TimeZoneInfo.ConvertTime(tokyo, tokyoTZ, estTZ);
// 変換方法③ : システム ID を使ってタイムゾーン間を直接変換する場合
DateTime est3 = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(tokyo, "Tokyo Standard Time",
"Eastern Standard Time");
// 2007/11/20 00:06:09 (EST)
Console.WriteLine("東京 : " + tokyo.ToString());
Console.WriteLine("UTC : " + utc.ToString());
Console.WriteLine("EST : " + est1.ToString() + " 夏時間 = " +
est1.IsDaylightSavingTime());
C#
OS の持つ一意識別名を
利用する
p.46
時差の取り扱い方
◼ (参考) .NET Framework 3.5 以前の場合
 .NET Framework 2.0, 3.0 において、任意のタイムゾーンの情報を
取得したり、時差補正を行うためには、以下の 2 つの方法がある
◼ 3rd party 製などのライブラリを利用する方法
◼ OS のレジストリからデータを読み取るライブラリを作成する方法
 以下を参照するとよい
◼ http://blogs.msdn.com/bclteam/archive/2006/04/03/567119.aspx
◼ http://www.gotdotnet.com/Community/UserSamples/Details.aspx?S
ampleGuid=0C9E8F33-7214-4222-B992-D248D107652F

More Related Content

.NET Framework におけるタイムゾーンの取り扱い

  • 1. .NET Framework における タイムゾーンの取り扱い Microsoft Corporation Nobuyuki Akama https://blogs.msdn.microsoft.com/nakama/ @nakama00 © 2018 Microsoft Corporation. All rights reserved. 本書の全部または一部の無断転載を禁じます。
  • 2. p.2 時差情報の管理(タイムゾーン情報) ◼ 国際化アプリケーションで時刻を扱う場合には、時差に関す る正しい取り扱いが必要になる ◼ 時差を考慮しながら時刻を正しく取り扱うためには、以下の 内容を理解する必要がある  0. 時差とは何か  1. 世界標準時(UTC)と地方標準時  2. 夏時間の補正  3. Windows OS におけるタイムゾーンの管理  4. カルチャ情報とタイムゾーン情報の違い ◼ これらについて解説する
  • 3. p.3 時差情報の管理(タイムゾーン情報) -0. 時差とは何か ◼ 時差とは、地域ごとの経度の違いから来る時間の差  一般に、各地域の時刻(時計)は、太陽の平均南中時刻が 12 時に なるように定められている  地球は反時計回りに自転しているため、太陽が南中する時刻が、地 球の場所ごとによってずれる 日本が最も 早く、南中を 迎える イギリスは 日本より 遅れて南中 アメリカはさらに それより遅れて 太陽が南中 日付変更線 (地球上で最も 早く太陽が南中 する場所) 2009/06/17 05:37:51 2009/06/16 21:37:51 2009/06/16 13:37:51
  • 4. p.4 時差情報の管理(タイムゾーン情報) -1. 世界標準時(UTC)と地方標準時 ◼ こうした時差をうまく取り扱うために、世界標準時と地方標準 時が利用されている  世界標準時(UTC/GMT、協定標準時/世界標準時)とは... ◼ 経度 0 度(イギリスのロンドンのグリニッジ天文台)での太陽の平均南中 時刻を正午とした時刻系 ※ これを GMT, グリニッジ標準時と呼ぶ  地方標準時とは... ◼ 各国や地域(タイムゾーン)において定められた時刻 ◼ 例えば、日本の場合は UTC に対して 9 時間早められた時計を使う、と 定められている UTC / GMT (世界標準時) (Coordinated Universal Time) JST (日本標準時) (Coordinated Universal Time) 2006/05/05 00:00:00 GMT 2006/05/05 09:00:00 JST JST = UTC+09:00 と書く ※ UTC と GMT は厳密には 異なるが、実質的には同じ ものだと考えて差し支えない
  • 5. p.5 時差情報の管理(タイムゾーン情報) -1. 世界標準時(UTC)と地方標準時 ◼ 時刻を表す際は「どの地域の時刻か」を付記する必要がある  正しい時刻の書き方について ◼ 単純に "2006/05/05 00:00:00" と記述すると、それが世界標準時なの か、地方標準時なのかが分からなくなる ◼ このため、通常は日時の末尾に 3 文字のアルファベット文字を付与し、 それがどの地方標準時でのものなのかを明示する  世界標準時と地方標準時との変換について ◼ 地方標準時と世界標準時とのずれは UTC±XX:XX の形式で書かれる ◼ これを元に、世界標準時と地方標準時を変換すればよい ◼ 例) JST での時刻 = UTC での時刻 + 09:00 地方標準時 UTC とのずれ 具体例 イギリス GMT (グリニッジ標準時) UTC+00:00 2006/05/05 00:00:00 GMT 日本 JST (日本標準時) UTC+09:00 2006/05/05 09:00:00 JST アメリカ西海岸(冬場) PST (太平洋標準時) UTC-08:00 2006/05/04 16:00:00 PST
  • 6. p.6 具体例 利用している国・地域 方角 GMT/UTC-12:00 -12:00 (12時間遅れている) JST+03:00 -21:00 (21時間遅れている) 2006/05/03 01:27:00 ベイカー島 西側 GMT/UTC-11:00 -11:00 (11時間遅れている) JST+04:00 -20:00 (20時間遅れている) 2006/05/03 02:27:00 ミッドウェー島、サモア GMT/UTC-10:00 -10:00 (10時間遅れている) JST+05:00 -19:00 (19時間遅れている) 2006/05/03 03:27:00 ハワイ GMT/UTC-09:00 -09:00 (9時間遅れている) JST+06:00 -18:00 (18時間遅れている) 2006/05/03 04:27:00 アラスカ GMT/UTC-08:00 -08:00 (8時間遅れている) JST+07:00 -17:00 (17時間遅れている) 2006/05/03 05:27:00 アメリカ太平洋時間 (米国およびカナダ)、ティファナ GMT/UTC-07:00 -07:00 (7時間遅れている) JST+08:00 -16:00 (16時間遅れている) 2006/05/03 06:27:00 アメリカ山地時間 (米国およびカナダ)、アリゾナ、チワワ、ラパス、 マサトラン GMT/UTC-06:00 -06:00 (6時間遅れている) JST+09:00 -15:00 (15時間遅れている) 2006/05/03 07:27:00 アメリカ中部時間 (米国およびカナダ), メキシコシティ、モンテレー、 サスカチュワン、中央アメリカ GMT/UTC-05:00 -05:00 (5時間遅れている) JST+10:00 -14:00 (14時間遅れている) 2006/05/03 08:27:00 アメリカ東部時間 (米国およびカナダ)、インディアナ東部、ボゴタ、 リマ、キト GMT/UTC-04:00 -04:00 (4時間遅れている) JST+11:00 -13:00 (13時間遅れている) 2006/05/03 09:27:00 大西洋標準時(カナダ)、カラカス、サンティアゴ、ラパス GMT/UTC-03:30 -03:30 (3.5時間遅れている) JST+11:30 -12:30 (12.5時間遅れている) 2006/05/03 09:57:00 ニューファンドランド GMT/UTC-03:00 -03:00 (3時間遅れている) JST-12:00 -12:00 (12時間遅れている) 2006/05/03 10:27:00 グリーンランド、ブレノスアイレス、ジュージタウン、ブラジリア GMT/UTC-02:00 -02:00 (2時間遅れている) JST-11:00 -11:00 (11時間遅れている) 2006/05/03 11:27:00 中央大西洋 GMT/UTC-01:00 -01:00 (1時間遅れている) JST-10:00 -10:00 (10時間遅れている) 2006/05/03 12:27:00 カーボベルデ諸島、アゾレス諸島 GMT/UTC (基準) JST-09:00 -09:00 (9時間遅れている) 2006/05/03 13:27:00 カサブランカ、モンロビア、ダブリン、エジンバラ、リスボン、ロンドン (グリニッジ標準時) GMT/UTC+01:00 +01:00 (1時間進んでいる) JST-08:00 -08:00 (8時間遅れている) 2006/05/03 14:27:00 アムステルダム、ベルリン、ベルン、ローマ、ストックホルム、ウィー ン、サラエボ、スコピエ、ワルシャワ、ザグレブ、ブリュッセル、コペン ハーゲン、マドリード、パリ、ベオグラード、プラチスラバ、ブダペス ト、リュブリャナ、プラハ、西中央アフリカ GMT/UTC+02:00 +02:00 (2時間進んでいる) JST-07:00 -07:00 (7時間遅れている) 2006/05/03 15:27:00 アテネ、ベイルート、イスタンブール、ミンスク、エルサレム、カイロ、 ハラーレ、プレトリア、ブカレスト、ヘルシンキ、キエフ、リガ、ソフィ ア、タリン、ビリニュス GMT/UTC+03:00 +03:00 (3時間進んでいる) JST-06:00 -06:00 (6時間遅れている) 2006/05/03 16:27:00 クウェート、リヤド、ナイロビ、バグダッド、モスクワ、サンクトペテル スブルグ、ボルゴグラード GMT/UTC+03:30 +03:00 (3.5時間進んでいる) JST-05:30 -05:30 (5.5時間遅れている) 2006/05/03 16:57:00 テヘラン GMT/UTC+04:00 +04:00 (4時間進んでいる) JST-05:00 -05:00 (5時間遅れている) 2006/05/03 17:27:00 アブダビ、マスカット、バク、トビリシ、エレバン GMT/UTC+04:30 +04:30 (4.5時間進んでいる) JST-04:30 -04:30 (4.5時間遅れている) 2006/05/03 16:57:00 カブール GMT/UTC+05:00 +05:00 (5時間進んでいる) JST-04:00 -04:00 (4時間遅れている) 2006/05/03 18:27:00 イスラマバード、カラチ、タシケント、エカテリンバーグ GMT/UTC+05:30 +05:30 (5.5時間進んでいる) JST-03:30 -03:30 (3.5時間遅れている) 2006/05/03 18:57:00 チェンナイ、コルカタ、ムンバイ、ニューデリー GMT/UTC+05:45 +05:45 (5.75時間進んでいる) JST-03:15 -03:15 (3.25時間遅れている) 2006/05/03 19:12:00 カトマンズ GMT/UTC+06:00 +06:00 (6時間進んでいる) JST-03:00 -03:00 (3時間遅れている) 2006/05/03 19:27:00 ダッカ、アスタナ、アルマティ、ノボシビルスク、スリ・ジャヤワルダナ GMT/UTC+06:30 +06:30 (6.5時間進んでいる) JST-02:30 -02:30 (2.5時間遅れている) 2006/05/03 19:57:00 ラングーン GMT/UTC+07:00 +07:00 (7時間進んでいる) JST-02:00 -02:00 (2時間遅れている) 2006/05/03 20:27:00 クラスノヤルスク、バンコク、ハノイ、ジャカルタ GMT/UTC+08:00 +08:00 (8時間進んでいる) JST-01:00 -01:00 (1時間遅れている) 2006/05/03 21:27:00 イルクーツク、ウランバートル、クアラルンプール、シンガポール、 パース、台北、北京、長慶、香港、ウルムチ GMT/UTC+09:00 +09:00 (9時間進んでいる) JST (基準) 2006/05/03 22:27:00 ソフル、ヤクーツク、大阪、札幌、東京 GMT/UTC+09:30 +09:30 (9.5時間進んでいる) JST+00:30 +00:30 (.5時間進んでいる) 2006/05/03 22:57:00 アデレード、ダーウィン GMT/UTC+10:00 +10:00 (10時間進んでいる) JST+01:00 +01:00 (1時間進んでいる) 2006/05/03 23:27:00 ウラジオストク、キャンベラ、メルボルン、シドニー、グアム、ポートモ レスビー、ブリスベン、ホバート GMT/UTC+11:00 +11:00 (11時間進んでいる) JST+02:00 +02:00 (2時間進んでいる) 2006/05/04 00:27:00 マガダン、ソロモン諸島、ニューカレドニア GMT/UTC+12:00 +12:00 (12時間進んでいる) JST+03:00 +03:00 (3時間進んでいる) 2006/05/04 01:27:00 オークランド、ウェリントン、フィジー、カムチャッカ、マーシャル諸島 GMT/UTC+13:00 +13:00 (13時間進んでいる) JST+04:00 +04:00 (4時間進んでいる) 2006/05/04 02:27:00 トンガ、ヌクアロファ GMT/UTC+14:00 +14:00 (14時間進んでいる) JST+05:00 +05:00 (5時間進んでいる) 2006/05/04 03:27:00 キリバス(クリスマス島) 東側 UTCに対する時差 日本に対する時差 代表的なタイムゾーン(※ サマータイム未考慮) 夏時間を意識しない 場合の日時 ※ 「遅れている」「進んでいる」と 時刻の加減算の関係に注意
  • 7. p.7 時差情報の管理(タイムゾーン情報) -1. 世界標準時(UTC)と地方標準時 ◼ 世界標準時と地方標準時とのずれをオフセット値と呼ぶ  (GMT 以外の)JST, EST などは国際的に定められた表記ではない  このため、オフセット値を使って表記するのが正しい記述方法 ◼ 例) 以下の表記はすべて「同一の日時」を指す  時差を考慮すると、すべて同じ時刻(瞬間)を表現していることになる UTC / GMT (世界標準時) UTC = UTC + 00:00 JST (日本標準時) JST = UTC + 09:00 2007/11/20 15:32:10 +09:00 PST (太平洋標準時) PST = UTC - 08:00 2007/11/20 15:32:10 JST 2007/11/20 06:32:10 +00:00 2007/11/20 06:32:10 GMT 2007/11/19 22:32:10 -08:00 2007/11/19 22:32:10 PST = = = = オフセット値 (UTC に対するずれ)
  • 8. p.8 時差情報の管理(タイムゾーン情報) -1. 世界標準時(UTC)と地方標準時 ◼ (当たり前だが)異なるタイムゾーンの時刻データ同士を差し 引きしても、正しい時間は算出できない  いったん UTC に変換すれば、正しい時間が算出できる  具体例) 成田 2009/01/03 15:00 発 ロサンゼルス 2009/01/03 09:00 着の飛行機のフライト時間は? いったん UTC に 変換 2009/01/03 09:00 PST 2009/01/03 15:00 JST イギリス 成田 ロサン ゼルス 01/03 06:00 UTC 01/03 15:00 JST 01/03 17:00 UTC 01/03 09:00 PST 11 時間のフライト
  • 9. p.9 時差情報の管理(タイムゾーン情報) -1. 世界標準時(UTC)と地方標準時 ◼ 同じ国の中に複数のタイムゾーンがあるケースがあることに も注意する  具体例) アメリカの場合 ◼ 本土だけでも EST, CST, MST, PST の 4 つのタイムゾーンがある ◼ 同様に、ロシアの場合には、国内に 10 個のタイムゾーンがある  同一の国 = 同一のタイムゾーンとは限らないことに注意する タイムゾーン名 略称 オフセット 主な都市 東海岸標準時 Eastern Standard Time EST UTC - 05:00 ニューヨーク、ワシントン、ボストン 中西部標準時 Central Standard Time CST UTC - 06:00 シカゴ、ヒューストン、ダラス 山岳部標準時 Mountain Standard Time MST UTC - 07:00 フェニックス、デンバー 太平洋標準時 Pacific Standard Time PST UTC - 08:00 ロサンゼルス、ラスベガス、シアトル
  • 10. p.10 時差情報の管理(タイムゾーン情報) -2. 夏時間の補正 ◼ 夏時間(サマータイム, Daylight Saving Time)とは、夏場の 時計を一定時間遅らせるものである  夏場の日没時刻を見かけ上遅らせて、経済活動を活性化させる  具体例) アメリカ太平洋側の標準時(PST, 太平洋標準時)の場合 ◼ 4 月第一日曜午前 2 時から 10 月最終日曜の午前 2 時が 1 時間シフト ◼ システム的には、タイムゾーンが変更されたとして取り扱われる  PST (太平洋標準時) = UTC-08:00  PDT (太平洋夏時間) = UTC-07:00 2006/01/01 00:00:00 2006/12/31 12:59:59 2006/04/02 02:00:00 PDT (太平洋夏時間) 2006/04/02 03:00:00 2006/10/29 02:00:00 2006/10/29 01:00:00 DaylightTime.Start DaylightTime.End DaylightTime.Delta 夏時間 オフセット値が 変化する! PST (太平洋標準時)
  • 11. p.11 1 時間 スキップする PDT に変更 (UTC-07:00) PST (UTC-08:00) PST に変更 (UTC-08:00) PDT (UTC-07:00) 1 時間 巻き戻る Windows XP の場合 ※ Windows Vista 以降の OS では、 タイムゾーン表記が直接的に変わる 様子を見ることができなくなってしま ったが、内部動作は同じ
  • 12. p.12 時差情報の管理(タイムゾーン情報) -2. 夏時間の補正 ◼ 夏時間は、政治的な理由によって決定されるものである  サマータイムの開始・終了日時、ずらす時間は国によって異なり、さら に年次や法律改正などによって変更される  Windows OS の場合、サマータイムの情報はタイムゾーン情報と併 せてレジストリで管理されている ◼ Vista 以降の OS では、自動的にデータが更新されるようになっている (Dynamic DST(Daylight Saving Time) 機能) ◼ XP, 2003 などでは Windows Update による更新が必要 導入国 開始日時 終了日時 デルタ 注記 アメリカ 3月最終日曜日1時 10月最終日曜日2時 1時間 2007年以降は期間変更 ヨーロッパ 3月最終日曜日1時 10月最終日曜日1時 1時間 ロシア 3月最終日曜日2時 10月最終日曜日3時 1時間 オーストラリア 10月最終日曜日2時 翌年3月最終日曜日3時 1時間 ニュージーランド 10月最終日曜日2時 翌年3月最終日曜日3時 1時間 ブラジル 10月第3日曜日0時 翌年2月第3日曜日0時 1時間 日本 5月第1土曜日24時 9月第2土曜日24時 1時間 1952年に廃止
  • 13. p.13 時差情報の管理(タイムゾーン情報) -2. 夏時間の補正 ◼ 同一のタイムゾーンであっても、夏時間がある場合には、単 純な時刻の加減算処理を行ってはならない!  具体例) アメリカ太平洋側における、以下の 2 つの日時の差は? ◼ 2006/04/02 01:00 (冬時間) ◼ 2006/04/02 05:00 (夏時間)  このような場合も、いったん UTC に変換してから計算するとラク いったん UTC に 変換 2009/01/03 09:00 PST 2009/01/03 15:00 JST 3 時間差 イギリス アメリカ太平 洋冬時間 アメリカ太平 洋夏時間 UTC PST = UTC - 08:00 PDT = UTC - 07:00 2006/04/02 09:00 UTC 2006/04/02 01:00 PST 2006/04/02 12:00 UTC 2006/04/02 05:00 PDT 見かけは 4 時間差だが...
  • 14. p.14 時差情報の管理(タイムゾーン情報) -3. Windows OS におけるタイムゾーンの管理 ◼ Windows OS では、これらのタイムゾーン情報がレジストリ で管理されている  エンドユーザは、自分が属するタイムゾーンを選択することになる  これにより、指定したタイムゾーンに関するオフセット情報が利用され るようになる コンピュータの タイムゾーン設定 レジストリのタイムゾーン情報 (HKEY_LOCAL_MACHINE¥SOFTWARE ¥Microsoft¥Windows NT¥CurrentVersion ¥TimeZones) ※ 直接いじってはいけない 設定したタイムゾーンで 日時が表示される
  • 15. p.15 時差情報の管理(タイムゾーン情報) -3. Windows OS におけるタイムゾーンの管理 ◼ (参考) Windows OS におけるタイムゾーンの管理方法  OS が管理しているタイムゾーンは約 80 種類  表示名(DisplayName), 地方標準時名(StandardName), 夏時間 名(Daylight Name)は OS の言語により変化するので注意する タイムゾーン識別 ID UTC に対す る時差(お セット) 表示名 地方標準時名 夏時間 有無 夏時間名 GMT Standard Time +00:00:00 (GMT) グリニッジ標準時: ダブリン、エ ジンバラ、リスボン、ロンドン GMT 標準時 True GMT 夏時間 Tokyo Standard Time +09:00:00 (GMT+09:00) 大阪、札幌、東京 東京 (標準時) False - Atlantic Standard Time -04:00:00 (GMT-04:00) 大西洋標準時 (カナダ) 大西洋標準時 True 大西洋夏時間 Eastern Standard Time -05:00:00 (GMT-05:00) 東部標準時 (米国および カナダ) 東部標準時 True 東部夏時間 Central Standard Time -06:00:00 (GMT-06:00) 中部標準時 (米国および カナダ) 中部標準時 True 中部夏時間 Pacific Standard Time -08:00:00 (GMT-08:00) 太平洋標準時 (米国およ びカナダ) 太平洋標準時 True 太平洋夏時間 この部分は OS の言語に依存しない
  • 16. p.16 時差情報の管理(タイムゾーン情報) -3. Windows OS におけるタイムゾーンの管理 タイムゾーン識別 ID UTC に対する時差 表示名 地方標準時名 夏時間有無 夏時間名 Id BaseUtcOffset DisplayName StandardName SupportsDaylightSavingTime DaylightName Greenwich Standard Time 00:00:00 (GMT) カサブランカ、モンロビア、レイキャビ ク グリニッジ標準時 False グリニッジ夏時間 GMT Standard Time 00:00:00 (GMT) グリニッジ標準時: ダブリン、エジンバ ラ、リスボン、ロンドン GMT 標準時 True GMT 夏時間 W. Europe Standard Time 01:00:00 (GMT+01:00) アムステルダム、ベルリン、ベ ルン、ローマ、ストックホルム、ウィーン 西ヨーロッパ標準時 True 西ヨーロッパ夏時間 Central European Standard Time 01:00:00 (GMT+01:00) サラエボ、スコピエ、ワルシャ ワ、ザグレブ 中央ヨーロピアン標準時 True 中央ヨーロピアン夏時間 Romance Standard Time 01:00:00 (GMT+01:00) ブリュッセル、コペンハーゲ ン、マドリード、パリ ロマンス標準時 True ロマンス夏時間 Central Europe Standard Time 01:00:00 (GMT+01:00) ベオグラード、ブラチスラバ、 ブダペスト、リュブリャナ、プラハ 中央ヨーロッパ標準時 True 中央ヨーロッパ夏時間 W. Central Africa Standard Time 01:00:00 (GMT+01:00) 西中央アフリカ 西中央アフリカ標準時 False 西中央アフリカ夏時間 GTB Standard Time 02:00:00 (GMT+02:00) アテネ、ブカレスト、イスタン ブール GTB 標準時 True GTB 夏時間 Jordan Standard Time 02:00:00 (GMT+02:00) アンマン ヨルダン標準時 True ヨルダン夏時間 Namibia Standard Time 02:00:00 (GMT+02:00) ウィントフック ナミビア標準時 True ナミビア夏時間 Israel Standard Time 02:00:00 (GMT+02:00) エルサレム エルサレム標準時 True エルサレム夏時間 Egypt Standard Time 02:00:00 (GMT+02:00) カイロ エジプト標準時 True エジプト夏時間 South Africa Standard Time 02:00:00 (GMT+02:00) ハラーレ、プレトリア 南アフリカ標準時 False 南アフリカ夏時間 FLE Standard Time 02:00:00 (GMT+02:00) ヘルシンキ、キエフ、リガ、ソ フィア、タリン、ビリニュス FLE 標準時 True FLE 夏時間 Middle East Standard Time 02:00:00 (GMT+02:00) ベイルート 中東標準時 True 中東夏時間 E. Europe Standard Time 02:00:00 (GMT+02:00) ミンスク 東ヨーロッパ標準時 True 東ヨーロッパ夏時間 Arab Standard Time 03:00:00 (GMT+03:00) クウェート、リヤド アラブ標準時 False アラブ夏時間 Georgian Standard Time 03:00:00 (GMT+03:00) トビリシ グルジア標準時 False グルジア夏時間 E. Africa Standard Time 03:00:00 (GMT+03:00) ナイロビ 東アフリカ標準時 False 東アフリカ夏時間 Arabic Standard Time 03:00:00 (GMT+03:00) バグダッド アラビック標準時 True アラビック夏時間 (参考) Windows OS のタイムゾーン情報一覧 1/5
  • 17. p.17 時差情報の管理(タイムゾーン情報) -3. Windows OS におけるタイムゾーンの管理 タイムゾーン識別 ID UTC に対する時差 表示名 地方標準時名 夏時間有無 夏時間名 Id BaseUtcOffset DisplayName StandardName SupportsDaylightSavingTime DaylightName Russian Standard Time 03:00:00 (GMT+03:00) モスクワ、サンクト ペテルスブ ルグ、ボルゴグラード ロシア標準時 True ロシア夏時間 Iran Standard Time 03:30:00 (GMT+03:30) テヘラン イラン標準時 True イラン夏時間 Arabian Standard Time 04:00:00 (GMT+04:00) アブダビ、マスカット アラビア標準時 False アラビア夏時間 Armenian Standard Time 04:00:00 (GMT+04:00) エレバン アルメニア標準時 True アルメニア夏時間 Caucasus Standard Time 04:00:00 (GMT+04:00) コーカサス標準時 コーカサス標準時 False コーカサス夏時間 Azerbaijan Standard Time 04:00:00 (GMT+04:00) バク アゼルバイジャン標準時 True アゼルバイジャン夏時間 Afghanistan Standard Time 04:30:00 (GMT+04:30) カブール アフガニスタン標準時 False アフガニスタン夏時間 West Asia Standard Time 05:00:00 (GMT+05:00) イスラマバード、カラチ、タシケ ント 西アジア標準時 False 西アジア夏時間 Ekaterinburg Standard Time 05:00:00 (GMT+05:00) エカテリンバーグ エカテリンバーグ標準時 True エカテリンバーグ夏時間 Sri Lanka Standard Time 05:30:00 (GMT+05:30) スリ・ジャヤワルダナプラ スリランカ標準時 False スリランカ夏時間 India Standard Time 05:30:00 (GMT+05:30) チェンナイ、コルカタ、ムンバ イ、ニューデリー インド標準時 False インド夏時間 Nepal Standard Time 05:45:00 (GMT+05:45) カトマンズ ネパール標準時 False ネパール夏時間 Central Asia Standard Time 06:00:00 (GMT+06:00) アスタナ、ダッカ 中央アジア標準時 False 中央アジア夏時間 N. Central Asia Standard Time 06:00:00 (GMT+06:00) アルマティ、ノボシビルスク 中央アジア北標準時 True 中央アジア北夏時間 Myanmar Standard Time 06:30:00 (GMT+06:30) ヤンゴン (ラングーン) ミャンマー標準時 False ミャンマー夏時間 North Asia Standard Time 07:00:00 (GMT+07:00) クラスノヤルスク 北アジア標準時 True 北アジア夏時間 SE Asia Standard Time 07:00:00 (GMT+07:00) バンコク、ハノイ、ジャカルタ 東南アジア標準時 False 東南アジア夏時間 North Asia East Standard Time 08:00:00 (GMT+08:00) イルクーツク、ウランバートル 北アジア東標準時 True 北アジア東夏時間 Singapore Standard Time 08:00:00 (GMT+08:00) クアラルンプール、シンガポー ル マレー半島標準時 False マレー半島夏時間 W. Australia Standard Time 08:00:00 (GMT+08:00) パース 西オーストラリア標準時 True 西オーストラリア夏時間 (参考) Windows OS のタイムゾーン情報一覧 2/5
  • 18. p.18 時差情報の管理(タイムゾーン情報) -3. Windows OS におけるタイムゾーンの管理 タイムゾーン識別 ID UTC に対する時差 表示名 地方標準時名 夏時間有無 夏時間名 Id BaseUtcOffset DisplayName StandardName SupportsDaylightSavingTime DaylightName China Standard Time 08:00:00 (GMT+08:00) 北京、重慶、香港、ウルムチ 中国 (標準時) False 中国 (夏時間) Taipei Standard Time 08:00:00 (GMT+08:00) 台北 台北 (標準時) False 台北 (夏時間) Korea Standard Time 09:00:00 (GMT+09:00) ソウル 韓国 (標準時) False 韓国 (夏時間) Yakutsk Standard Time 09:00:00 (GMT+09:00) ヤクーツク ヤクーツク標準時 True ヤクーツク夏時間 Tokyo Standard Time 09:00:00 (GMT+09:00) 大阪、札幌、東京 東京 (標準時) False 東京 (夏時間) Cen. Australia Standard Time 09:30:00 (GMT+09:30) アデレード 中央オーストラリア標準時 True 中央オーストラリア夏時間 AUS Central Standard Time 09:30:00 (GMT+09:30) ダーウィン AUS 中央標準時 False AUS 中央夏時間 Vladivostok Standard Time 10:00:00 (GMT+10:00) ウラジオストク ウラジオストク標準時 True ウラジオストク夏時間 AUS Eastern Standard Time 10:00:00 (GMT+10:00) キャンベラ、メルボルン、シド ニー AUS 東部標準時 True AUS 東部夏時間 West Pacific Standard Time 10:00:00 (GMT+10:00) グアム、ポートモレスビー 西太平洋 (標準時) False 西太平洋 (夏時間) E. Australia Standard Time 10:00:00 (GMT+10:00) ブリスベン 東オーストラリア標準時 False 東オーストラリア夏時間 Tasmania Standard Time 10:00:00 (GMT+10:00) ホバート タスマニア標準時 True タスマニア夏時間 Central Pacific Standard Time 11:00:00 (GMT+11:00) マガダン、ソロモン諸島、 ニューカレドニア 中央太平洋 (標準時) False 中央太平洋 (夏時間) New Zealand Standard Time 12:00:00 (GMT+12:00) オークランド、ウェリントン ニュージーランド標準時 True ニュージーランド夏時間 Fiji Standard Time 12:00:00 (GMT+12:00) フィジー、カムチャツカ、マー シャル諸島 フィジー標準時 False フィジー夏時間 Tonga Standard Time 13:00:00 (GMT+13:00) ヌクアロファ トンガ標準時 False トンガ夏時間 Azores Standard Time -01:00:00 (GMT-01:00) アゾレス諸島 アゾレス諸島標準時 True アゾレス諸島夏時間 Cape Verde Standard Time -01:00:00 (GMT-01:00) カーボベルデ諸島 カーボベルデ標準時 False カーボベルデ夏時間 Mid-Atlantic Standard Time -02:00:00 (GMT-02:00) 中央大西洋 中央大西洋標準時 True 中央大西洋夏時間 Greenland Standard Time -03:00:00 (GMT-03:00) グリーンランド グリーンランド標準時 True グリーンランド夏時間 (参考) Windows OS のタイムゾーン情報一覧 3/5
  • 19. p.19 時差情報の管理(タイムゾーン情報) -3. Windows OS におけるタイムゾーンの管理 タイムゾーン識別 ID UTC に対する時差 表示名 地方標準時名 夏時間有無 夏時間名 Id BaseUtcOffset DisplayName StandardName SupportsDaylightSavingTime DaylightName SA Eastern Standard Time -03:00:00 (GMT-03:00) ブエノスアイレス、ジョージタウ ン SA 東部標準時 False SA 東部夏時間 E. South America Standard Time -03:00:00 (GMT-03:00) ブラジリア 南アメリカ東部標準時 True 南アメリカ東部夏時間 Montevideo Standard Time -03:00:00 (GMT-03:00) モンテビデオ モンテビデオ標準時 True モンテビデオ夏時間 Newfoundland Standard Time -03:30:00 (GMT-03:30) ニューファンドランド ニューファンドランド標準時 True ニューファンドランド夏時間 SA Western Standard Time -04:00:00 (GMT-04:00) カラカス、ラパス 南アメリカ西部標準時 False 南アメリカ西部夏時間 Pacific SA Standard Time -04:00:00 (GMT-04:00) サンティアゴ 太平洋南アメリカ標準時 True 太平洋南アメリカ夏時間 Central Brazilian Standard Time -04:00:00 (GMT-04:00) マナウス 中央ブラジル標準時 True 中央ブラジル夏時間 Atlantic Standard Time -04:00:00 (GMT-04:00) 大西洋標準時 (カナダ) 大西洋標準時 True 大西洋夏時間 US Eastern Standard Time -05:00:00 (GMT-05:00) インディアナ東部 米国 東部標準時 False 米国 東部夏時間 SA Pacific Standard Time -05:00:00 (GMT-05:00) ボゴタ、リマ、キト、リオ ブラン コ 南アメリカ太平洋標準時 False 南アメリカ太平洋夏時間 Eastern Standard Time -05:00:00 (GMT-05:00) 東部標準時 (米国およびカナ ダ) 東部標準時 True 東部夏時間 Central Standard Time (Mexico) -06:00:00 (GMT-06:00) グアダラハラ、メキシコシティ、 モンテレー - 新 中部標準時 (メキシコ) True 中部夏時間 (メキシコ) Mexico Standard Time -06:00:00 (GMT-06:00) グアダラハラ、メキシコシティ、 モンテレー - 旧 メキシコ標準時 True メキシコ夏時間 Canada Central Standard Time -06:00:00 (GMT-06:00) サスカチュワン カナダ中部標準時 False カナダ中部夏時間 Central America Standard Time -06:00:00 (GMT-06:00) 中央アメリカ 中央アメリカ標準時 False 中央アメリカ夏時間 Central Standard Time -06:00:00 (GMT-06:00) 中部標準時 (米国およびカナ ダ) 中部標準時 True 中部夏時間 US Mountain Standard Time -07:00:00 (GMT-07:00) アリゾナ 米国 山地標準時 False 米国 山地夏時間 Mountain Standard Time (Mexico) -07:00:00 (GMT-07:00) チワワ、ラパス、マサトラン - 新 山地標準時 (メキシコ) True 山地夏時間 (メキシコ) Mexico Standard Time 2 -07:00:00 (GMT-07:00) チワワ、ラパス、マサトラン - 旧 メキシコ 山地標準時 2 True メキシコ 山地夏時間 2 Mountain Standard Time -07:00:00 (GMT-07:00) 山地標準時 (米国およびカナ ダ) 山地標準時 True 山地夏時間 (参考) Windows OS のタイムゾーン情報一覧 4/5
  • 20. p.20 時差情報の管理(タイムゾーン情報) -3. Windows OS におけるタイムゾーンの管理 ◼ (参考) レジストリでのデータ管理について  JST, EST, PST, PDT などの表記は OS やレジストリでは管理され ていない(これらは通称であり正式表記ではないため)  Dymamic DST 機能は XP, 2003 でも条件付きで利用可能 ◼ 更新プログラムの適用に加えて、.NET Fx 3.5 のライブラリを利用する  詳細は以下の blog を参照 ◼ Exploring Windows Time Zones with System.TimeZoneInfo ◼ http://blogs.msdn.com/bclteam/archive/2007/06/07/exploring- windows-time-zones-with-system-timezoneinfo-josh-free.aspx タイムゾーン識別 ID UTC に対する時差 表示名 地方標準時名 夏時間有無 夏時間名 Id BaseUtcOffset DisplayName StandardName SupportsDaylightSavingTime DaylightName Pacific Standard Time (Mexico) -08:00:00 (GMT-08:00) ティファナ、バハカリフォルニア 太平洋標準時 (メキシコ) True 太平洋夏時間 (メキシコ) Pacific Standard Time -08:00:00 (GMT-08:00) 太平洋標準時 (米国およびカ ナダ) 太平洋標準時 True 太平洋夏時間 Alaskan Standard Time -09:00:00 (GMT-09:00) アラスカ アラスカ標準時 True アラスカ夏時間 Hawaiian Standard Time -10:00:00 (GMT-10:00) ハワイ ハワイ標準時 False ハワイ夏時間 Samoa Standard Time -11:00:00 (GMT-11:00) ミッドウェー島、サモア サモア標準時 False サモア夏時間 Dateline Standard Time -12:00:00 (GMT-12:00) 国際日付変更線 西側 日付変更線 (標準時) False 日付変更線 (夏時間) (参考) Windows OS のタイムゾーン情報一覧 5/5
  • 21. p.21 時差情報の管理(タイムゾーン情報) -4. カルチャ情報とタイムゾーン情報の違い ◼ 時刻データを取り扱う場合には、以下の 2 つの点に注意す る必要がある  ① カルチャとタイムゾーンの両方を同時に考える必要がある ◼ すべての日時データは、UTC 化すれば同一のものとして扱える ◼ これをローカライズする際は、カルチャとタイムゾーンの両方を意識する 必要がある  ② メッセージではなくデータのカルチャを考える必要がある ◼ 特定の日時をどの言語で表示するのかは、メッセージのカルチャではな くデータのカルチャにより決定する必要がある ◼ これらについて解説する
  • 22. p.22 時差情報の管理(タイムゾーン情報) -4. カルチャ情報とタイムゾーン情報の違い ◼ ① カルチャとタイムゾーンの両方を同時に考える必要がある  通貨や質量などのデータ値と異なり、日時データは、UTC に変換す れば、全世界のデータを共通に取り扱うことができる ◼ このため、日時データの加減算処理などを行う場合には、UTC に変換し ておけば間違いがなかった ◼ データベースに保存する際も、UTC に変換してから保存すれば、夏時間 であるか否かといったことを記述する必要もない  例) 単純に "2006/10/29 01:30" とだけ記述すると、冬時間なのか夏時間な のかがわからなくなってしまう!  しかし、UTC ベースで保存された値を表示する際には、タイムゾーン とカルチャの両方を考える必要が生じる ◼ まず、タイムゾーンを意識して、UTC で保存された時刻をローカル時刻 に変換する ◼ 次に、その時刻を、現地のカルチャに従った方法で表示する必要がある  具体例 → 次ページ
  • 23. p.23 ◼ 具体例) UTC 保存された日時データを正しく表示する方法  まずタイムゾーン変換をした後で、各カルチャで表示する 2007/11/20 06:32:10 (UTC) 2007/11/19 22:32:10 (PST) 2007/11/20 15:32:10 (JST) 時差情報の管理(タイムゾーン情報) -4. カルチャ情報とタイムゾーン情報の違い JST に変換 PST に変換 decimal = 100m; decimal = 100m; Tuesday, November 20, 2007 10:32:10 PM 2007年11月20日 15:32:10 ja-jp で表示 en-us で表示 $100.00¥100
  • 24. p.24 時差情報の管理(タイムゾーン情報) -4. カルチャ情報とタイムゾーン情報の違い ◼ ② メッセージではなくデータのカルチャを考える必要がある  特定の日時データをどの言語で表示するのかは、メッセージのカル チャではなくデータのカルチャによって決定される ◼ 具体例) "2007/11/20 15:32:10" というデータを表示する場合  データ値のカルチャが ja-jp の場合 → "2007 年 11 月 20 日 15:32:10"  メッセージのカルチャを en-us に変えても、データ値のカルチャが ja-jp の場 合には、日本語表示 "2007 年 11 月 20 日 15:32:10" になってしまう ◼ 具体例) Windows Vista のカレンダー  メッセージのカルチャ(=ユーザ UI 言語)を変更しても変わらない  データ値のカルチャ(=ユーザロケール)を変更すると切り替わる 英語 日本語 アラビア語
  • 25. p.25 時差情報の管理(タイムゾーン情報) -4. カルチャ情報とタイムゾーン情報の違い ◼ ② (続き)  OS のユーザロケール(データ値のカルチャ)を変更すると、 ◼ データ値の文字列化表示形式が変わり、カレンダー表示も変わる ◼ その他の表示はすべて日本語(=ユーザ UI 言語の設定)のまま 英語のカレンダーに 変わる! (他はすべて日本語)
  • 26. p.26 時差情報の管理(タイムゾーン情報) -4. カルチャ情報とタイムゾーン情報の違い ◼ ② (続き)  日付表記やカレンダー表示が、メッセージのカルチャではなくデータ のカルチャによって設定されるのは、以下のような理由による ◼ 「ある瞬間」(日時)をどのように解釈して表示するのかは、カルチャに よって変化する(=単なる言葉の違いだけではない)  1 週間は何日か?(※ 現在は全世界で七曜が使われている)  1 週間は何曜日始まりか?  各曜日の意味は?(※ 日曜日が休み、月曜日始まりとは限らない)  現地歴カレンダーとしては何が使われているか?(和暦など)  etc.  このため、日付表記やカレンダー表示の方式は、メッセージのカル チャではなくデータ値のカルチャによって設定しなければならない ◼ 直感と異なるため、十分に注意すること!
  • 27. p.27 時差情報の管理(タイムゾーン情報) -4. カルチャ情報とタイムゾーン情報の違い ◼ ② (続き)  前述の事項は、外国人が PC を利用する際に制約になることがある ◼ 例) 日本に在住 しているアメリカ 人の場合 英語版 OS ユーザロケール = ja-JP ユーザ UI 言語 = en-USアメリカ人 日本でお金を扱ったりする場合は 「ドル」ではなく「円」であるため、 ユーザロケールは変更する ユーザロケールを 反映するため、 カレンダーは 日本語表記になる OS の表示はユーザ UI 言語を反映するため、 英語表記になる
  • 28. p.28 時差情報の管理(タイムゾーン情報) -まとめ ◼ 国際化アプリケーションで時刻を扱う場合には、時差に関す る正しい取り扱いが必要になる ◼ キーポイントとしては以下の通り  同一の国・場所だからといって、タイムゾーンが共通とは限らない(特 に夏時間の存在に注意!)  アプリケーション内部では、地方標準時を UTC ベースに変換して、 オフセット情報と共に取り扱うと安全である  Windows OS は、タイムゾーン情報をレジストリで管理している  UTC ベースで保存された日時データを表示する際は、タイムゾーン 情報を基にオフセット変換したあと、カルチャに合わせた表示を行う  時刻の表示形式は、データ値のカルチャによって決定される
  • 30. p.30 時差の取り扱い方 ◼ .NET Framework での時差の取り扱い機能は、バージョン アップとともに強化されてきた  特に .NET Framework 3.5 では、時差やタイムゾーンを直接操作で きるライブラリが追加された  バージョンごとに利用可能な機能が異なるため、これらの 3 つのライ ブラリについて、利用方法と利用上の注意点を解説する DateTime DateTimeOffset TimeZoneInfo .NET Fx 1.0/1.1 △ 制限あり × 利用不可 × 利用不可 .NET Fx 2.0 ◎ × 利用不可 × 利用不可 .NET Fx 3.0 ◎ × 利用不可 × 利用不可 .NET Fx 3.5 ◎ ◎ ◎ A. で解説 B. で解説 C. で解説
  • 31. p.31 時差の取り扱い方 ◼ A. DateTime 型による日時の取り扱い  DateTime 型は、世界標準時(UTC)と地方標準時(Local)の取り扱 いが曖昧である ◼ 特に重要なのは、DateTime 型はデータが UTC/Local のどちらである かの情報は持つが、オフセット情報は持っていないという点である ◼ このため、十分注意して処理を記述しないと、計算ミスや時刻変換ミスを することになる  DateTime 型で日時を取り扱う場合には、以下の点に注意する必要 がある ◼ i. 地方標準時(Local)と世界標準時(UTC)間の時刻変換 ◼ ii. 加減算処理に関する挙動 ◼ iii. ToString() メソッドの挙動 ◼ iv. Parse(), ParseExact() メソッドの挙動
  • 32. p.32 時差の取り扱い方 ◼ A. DateTime 型による日時の取り扱い(続き)  i. 地方標準時(Local)と世界標準時(UTC)間の時刻変換 ◼ DateTime 型には、当該コンピュータに設定されたタイムゾーンの地方標 準時と、世界標準時(UTC)間の変換を行う機能が備わっている  .ToLocalTime() メソッド、.ToUniversalTime() メソッドにより変換する  注意: 任意のタイムゾーン間の時差補正を行う機能は備わっていない ◼ DateTime 型には、当該データが世界標準時、地方標準時のどちらであ るのかを示すフラグが備わっている  Kind プロパティ : Local, Utc, Unspecified(後述) の 3 つ  これにより、当該 DateTime データが、地方標準時のものなのか、世界標準 時のものなのかが明確化されるようになっている  このため、上記の時差補正メソッドを複数回呼び出しても、正しいデータ変換 が行われる (※ .NET Fx 2.0 の新機能) ◼ 具体的なコード例 → 次ページ
  • 33. p.33 // ※ 以下の処理結果は、すべてタイムゾーンが JST の PC 上で行った場合のもの // パターン① JST ベースの時刻を扱う場合 DateTime date1 = DateTime.Now; // 地方標準時による現在時刻を取得 Console.WriteLine(date1.Kind); // Local (地方標準時によるデータ) Console.WriteLine(date1); // 2006/05/05 20:44:37 Console.WriteLine(date1.ToLocalTime()); // 2006/05/05 20:44:37 Console.WriteLine(date1.ToUniversalTime()); // 2006/05/05 11:44:37 // パターン② UTC ベースの時刻を扱う場合 DateTime date2 = DateTime.UtcNow; // 世界標準時による現在時刻を取得 Console.WriteLine(date2.Kind); // Utc (世界標準時によるデータ) Console.WriteLine(date2); // 2006/05/05 11:44:37 Console.WriteLine(date2.ToLocalTime()); // 2006/05/05 20:44:37 Console.WriteLine(date2.ToUniversalTime()); // 2006/05/05 11:44:37 // パターン③ JST ベースの時刻を UTC ベースに変換してから扱う場合 DateTime date3 = date1.ToUniversalTime(); // 地方標準時を世界標準時に変換 Console.WriteLine(date3.Kind); // Utc (世界標準時によるデータ) Console.WriteLine(date3); // 2006/05/05 11:44:37 Console.WriteLine(date3.ToLocalTime()); // 2006/05/05 20:44:37 Console.WriteLine(date3.ToUniversalTime()); // 2006/05/05 11:44:37 C# JST → JST では 変化しない UTC → UTC では 変化しない
  • 34. p.34 時差の取り扱い方 ◼ A. DateTime 型による日時の取り扱い(続き)  ii. 加減算処理に関する挙動 ◼ DateTime 型は、そのデータがどのタイムゾーンに属するのか(=オフ セット値はいくつなのか)の情報を持たない  このため、加減算を地方標準時ベースで行うと誤った結果になる恐れがある ◼ 以下のパターンでの加減算処理は、正しい答えを返さない  ① 異なるタイムゾーンで表現された DateTime 値同士の加減算  ② 夏時間が存在するタイムゾーンの DateTime 値同士の加減算 ※ 同一タイムゾーンでも、夏時間変更またがりの 2 つの DateTime は、異な るオフセット値を持つことに注意! ◼ 正しい加減算を行うためには、UTC ベースで処理を行う  いったん UTC ベースの時刻に変換した上で、加減算処理を行う ◼ 具体例 → 次ページ参照
  • 35. p.35 時差の取り扱い方 // 具体例:夏時間補正タイミングにまたがった減算処理 DateTime date1 = DateTime.Now; // 地方標準時を取得 // 2006/10/29 01:59:49 PDT Console.WriteLine(date1); // 2006/10/29 01:59:49 Console.WriteLine(date1.IsDaylightSavingTime()); // True (夏時間) Console.WriteLine(date1.Kind); // Local (地方標準時) Console.WriteLine(date1.ToString("zzz")); // -07:00 ← PDT = UTC-07:00 Console.ReadLine(); DateTime date2 = DateTime.Now; // 夏時間終了後の地方標準時を取得 // 2006/10/29 01:00:08 PST Console.WriteLine(date2); // 2006/10/29 01:00:08 Console.WriteLine(date2.IsDaylightSavingTime()); // False (夏時間) Console.WriteLine(date2.Kind); // Local (地方標準時) Console.WriteLine(date2.ToString("zzz")); // -08:00 ← PST = UTC-08:00 // × 地方標準時ベースで計算すると、間違った答えになる TimeSpan span1 = date2.Subtract(date1); // ローカル時刻同士を差し引き Console.WriteLine(span1.TotalSeconds); // × -3581 sec (≒-00:59:41) // ◎ UTC ベースで計算すると、正しい答えになる TimeSpan span2 = date2.ToUniversalTime().Subtract(date1.ToUniversalTime()); // いったんUTCに変換してから差し引き Console.WriteLine(span2.TotalSeconds); // ◎ +19 sec C# OS のタイムゾーン設定 =PST/PDT (太平洋標準時) の場合
  • 36. p.36 時差の取り扱い方 // 具体例:夏時間補正タイミングにまたがった加算処理 // 夏時間が終了する直前の時刻に対して、5 分後の時刻を計算 DateTime date1 = DateTime.Now; // 地方標準時を取得 // 2006/10/29 01:59:49 PDT Console.WriteLine(date1); // 2006/10/29 01:59:49 Console.WriteLine(date1.IsDaylightSavingTime()); // True Console.WriteLine(date1.Kind); // Local Console.WriteLine(date1.ToString("zzz")); // -07:00 // × 地方標準時ベースで加算すると間違った答えになる DateTime date2 = date1.AddMinutes(5); // × 2006/10/29 02:04:49 PST Console.WriteLine(date2); // 2006/10/29 02:04:49 Console.WriteLine(date2.IsDaylightSavingTime()); // False Console.WriteLine(date2.Kind); // Local Console.WriteLine(date2.ToString("zzz")); // -08:00 ←PST=UTC-08:00 // ◎ UTC ベースで加算すると正しい答えになる DateTime date3 = date1.ToUniversalTime().AddMinutes(5).ToLocalTime(); // ◎ 2006/10/29 01:04:49 PST Console.WriteLine(date3); // 2006/10/29 01:04:49 Console.WriteLine(date3.IsDaylightSavingTime()); // False Console.WriteLine(date3.Kind); // Local Console.WriteLine(date3.ToString("zzz")); // -08:00 ←PST=UTC-08:00 C# OS のタイムゾーン設定 =PST/PDT (太平洋標準時) の場合
  • 37. p.37 時差の取り扱い方 ◼ A. DateTime 型による日時の取り扱い(続き)  iii. ToString() メソッドの挙動 ◼ .ToString() メソッドは世界標準時と地方標準時のどちらであるのかを一 切考慮しないため、アプリ側の配慮が必要になる  具体例) "r" (RFC1123)の場合 → Local 時刻であっても GMT 表記になる  具体例) "zzz" (タイムゾーンオフセット)の場合 → Utc 時刻であっても当該 PC のタイムゾーンオフセットを表示してしまう // ※ 正しい時刻は以下の通り // Fri, 05 May 2006 21:09:36 JST または 2006/05/05 21:09:36 (JST) // Fri, 05 May 2006 12:09:36 UTC または 2006/05/05 12:09:36 (UTC) // パターン① JST による時刻を扱う場合 DateTime date1 = DateTime.Now; // JST での現在時刻 Console.WriteLine(date1.ToString("r")); // × Fri, 05 May 2006 21:09:36 GMT Console.WriteLine(date1.ToString("yyyy/MM/dd HH:mm:ss (UTCzzz)")); // ◎ 2006/05/05 21:09:36 (UTC+09:00) // パターン② UTC による時刻を扱う場合 DateTime date2 = DateTime.UtcNow; // UTC での現在時刻 Console.WriteLine(date2.ToString("r")); // ◎ Fri, 05 May 2006 12:09:36 GMT Console.WriteLine(date2.ToString("yyyy/MM/dd HH:mm:ss (UTCzzz)")); // × 2006/05/05 12:09:36 (UTC+09:00) C# Local 時刻に対しては "r" や "R" を使ってはならない (UTC 変換してから使う)
  • 38. p.38 時差の取り扱い方 ◼ A. DateTime 型による日時の取り扱い(続き)  iv. Parse(), ParseExact() メソッドの挙動 ◼ .Parse(), .ParseExact() やコンストラクタで作成した日時は、世界標準 時・地方標準時のどちらであるかが不明なデータとして扱われる ◼ .ToUniversalTime() などを呼び出す際に不適切な計算をする恐れがあ るため、パース時に明示的に Local / Utc 設定を行うとよい // 特に指定をせずにコンストラクタやParse() 処理を行うと、Unspecified 扱いになる DateTime date1 = new DateTime(2006, 5, 4, 21, 19, 15); Console.WriteLine(date1); // 2006/05/04 21:19:15 Console.WriteLine(date1.ToUniversalTime()); // 2006/05/04 12:19:15 // ※ date1 が JST ベースと解釈された上で UTC に変換される Console.WriteLine(date1.ToLocalTime()); // 2006/05/05 06:19:15 // ※ date1 が UTC ベースと解釈された上で JST に変換される // Local/Utc どちらであるかを明示するためには、SpecifyKind() 命令を利用する DateTime date2 = DateTime.ParseExact("2006/05/04 21:19:15", "yyyy/MM/dd HH:mm:ss", DateTimeFormatInfo.InvariantInfo); DateTime.SpecifyKind(date2, DateTimeKind.Utc); // コンストラクタを使う場合には、パラメータとして明示的な指定ができる DateTime date3 = new DateTime(2006, 5, 4, 21, 19, 15, DateTimeKind.Utc); C# 当該データが Local/Utc の どちらであるのかを明示する
  • 39. p.39 時差の取り扱い方 ◼ A. DateTime 型による日時の取り扱い(続き)  まとめると、以下の通りとなる ◼ DateTime 型には、オフセット値を保持する機能がない  地方標準時か、世界標準時かを判定する機能しかない  このため、オフセット値については開発者側で意識する必要がある ◼ DateTime 型の時差補正は、PC のオフセット値を元にして計算される  その DateTime 値の「本当のオフセット値」を意識した変換は行わない ◼ DateTime 型の加減算処理を行う際は、必ず UTC を介して行う  DateTime 型は、「見た目の数値」をそのまま加減算処理する  たとえ同一タイムゾーンであったとしても、夏時間前後でオフセット値が変化 する恐れがあるため、必ず UTC を介して計算する ◼ ToString(), Parse(), ParseExact() 処理は、タイムゾーンやオフセット値 を一切考慮してくれない  内部に Kind フラグを持っているにもかかわらず、これらを無視して挙動する  このため、タイムゾーンやオフセットについては開発者側で注意する
  • 40. p.40 時差の取り扱い方 ◼ B. DateTimeOffset 型による日時の取り扱い  前述したような複雑な問題を解決するため、.NET Framework 3.5 で は「オフセット値も内部に保持できる」日時型が用意された ◼ DateTime 型 → 「地方標準時か否か」のフラグしか持てない ◼ DateTimeOffset 型 → 「オフセット値」を直接保持できる  オフセット値を直接保持できるため、前述したような問題はほとんど 発生しなくなる! // DateTime 型の場合 DateTime tokyo1 = DateTime.Now; Console.WriteLine(tokyo1); // ◎ 2007/11/20 15:09:45 Console.WriteLine(tokyo1.ToString("r")); // × Tue, 20 Nov 2007 15:09:45 GMT // DateTimeOffset 型の場合 DateTimeOffset tokyo2 = DateTimeOffset.Now; Console.WriteLine(tokyo2); // ◎ 2007/11/20 15:09:45 +09:00 Console.WriteLine(tokyo2.ToString("r")); // ◎ Tue, 20 Nov 2007 06:09:45 GMT C# フォーマットは GMT 表記だが 値は地方標準時のまま オフセット情報が自動的につき、 GMT 表記すると自動変換される
  • 41. p.41 時差の取り扱い方 ◼ B. DateTimeOffset 型による日時の取り扱い(続き)  具体例) 夏時刻補正タイミングまたがりでの加減算処理 // 具体例:夏時間補正タイミングにまたがった減算処理 DateTimeOffset date1 = DateTimeOffset.Now; // 地方標準時を取得 Console.WriteLine(date1); // 2006/10/29 01:59:49 -07:00 Console.WriteLine(date1.ToUniversalTime()); // 2006/10/29 08:59:49 +00:00 Console.ReadLine(); DateTimeOffset date2 = DateTimeOffset.Now; // 夏時間終了後の地方標準時を取得 Console.WriteLine(date2); // 2006/10/29 01:00:08 -08:00 Console.WriteLine(date2.ToUniversalTime()); // 2006/10/29 09:00:08 +00:00 // ◎ 地方標準時ベースで計算しても、正しい答えを返す TimeSpan span1 = date2.Subtract(date1); // ローカル時刻同士を差し引き Console.WriteLine(span1.TotalSeconds); // ◎ +19 sec C# OS のタイムゾーン設定 =PST/PDT (太平洋標準時) の場合
  • 42. p.42 時差の取り扱い方 ◼ B. DateTimeOffset 型による日時の取り扱い(続き)  具体例) .ToString() メソッドの振る舞い ◼ DateTimeOffset.Now や .UtcNow によるデータ取得時に、自動的にオ フセット情報も取り込まれる ◼ このため、"r" フォーマットや "zzz" フォーマットを利用した場合でも、適切 なデータを表示することができるようになっている // ※ 正しい時刻は以下の通り // Tue, 21 Nov 2006 16:56:51 JST または Tue, 21 Nov 2006 16:56:51 (+09:00) // Tue, 21 Nov 2006 07:56:51 UTC または Tue, 21 Nov 2006 07:56:51 (+00:00) // パターン① JST による時刻を扱う場合 DateTimeOffset date1 = DateTimeOffset.Now; // JST での現在時刻 Console.WriteLine(date1.ToString("r")); // ◎ Tue, 21 Nov 2006 07:56:51 GMT Console.WriteLine(date1.ToString("yyyy/MM/dd HH:mm:ss (UTCzzz)")); // ◎ 2006/11/21 16:56:51 (UTC+09:00) // パターン② UTC による時刻を扱う場合 DateTimeOffset date2 = DateTimeOffset.UtcNow; // UTC での現在時刻 Console.WriteLine(date2.ToString("r")); // ◎ Tue, 21 Nov 2006 07:56:51 GMT Console.WriteLine(date2.ToString("yyyy/MM/dd HH:mm:ss (UTCzzz)")); // ◎ 2006/11/21 07:56:51 (UTC+00:00) C# すべて正しい!
  • 43. p.43 時差の取り扱い方 ◼ B. DateTimeOffset 型による日時の取り扱い(続き)  具体例) .Parse() メソッドやコンストラクタの振る舞い ◼ DateTimeOffset 型は、オフセット情報を内部に保持する必要があるた め、データ作成時には必ずオフセット情報が必要になる DateTimeOffset date1 = new DateTimeOffset(2006, 5, 4, 21, 19, 15, TimeSpan.FromHours(9)); Console.WriteLine(date1); // 2006/05/04 21:19:15 +09:00 Console.WriteLine(date1.ToUniversalTime()); // 2006/05/04 12:19:15 +00:00 Console.WriteLine(date1.ToLocalTime()); // 2006/05/05 06:19:15 +09:00 // オフセット情報つき文字列を解析する (存在しない場合はローカル PC のオフセット値が利用される) DateTimeOffset date2 = DateTimeOffset.ParseExact("2006/05/04 21:19:15 +09:00", "yyyy/MM/dd HH:mm:ss zzz", DateTimeFormatInfo.InvariantInfo); Console.WriteLine(date2); // 2006/05/04 21:19:15 +09:00 // オフセットを後から指定する場合には、DateTime 型を経由するとよい DateTime temp = DateTime.ParseExact("2006/05/04 21:19:15", "yyyy/MM/dd HH:mm:ss", DateTimeFormatInfo.InvariantInfo); DateTimeOffset date3 = new DateTimeOffset(temp, TimeSpan.FromHours(-8)); Console.WriteLine(date3); // 2006/05/04 21:19:15 -08:00 Console.WriteLine(date3.ToUniversalTime()); // 2006/05/04 05:19:15 +00:00 C# オフセット値を明示
  • 44. p.44 時差の取り扱い方 ◼ C. タイムゾーン間の時差補正  DateTime 型や DateTimeOffset 型だけでは、世界標準時(UTC)と の間の変換しか行えない  任意のタイムゾーン間での時差補正を行うためには、.NET Framework 3.5 で導入された TimeZoneInfo クラスを利用する ◼ Windows OS のレジストリに格納されたタイムゾーン情報(80 個前後の タイムゾーン情報)を元に、タイムゾーン間の時刻変換を実施できる ※ (注意) 時差補正用データは、OS 側に依存していることに注意する (.NET Framework 内部にデータを持っているわけではない!)
  • 45. p.45 時差の取り扱い方 DateTime tokyo = DateTime.Now; // 2007/11/20 14:06:09 (JST) DateTime utc = tokyo.ToUniversalTime(); // 2007/11/20 05:06:09 (UTC) // 東部標準時 (EST) への変換 TimeZoneInfo estTZ = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); TimeZoneInfo tokyoTZ = TimeZoneInfo.Local; // 変換方法① : UTC 経由で変換する場合 DateTime est1 = TimeZoneInfo.ConvertTimeFromUtc(utc, estTZ); // 変換方法② : 直接変換する場合 DateTime est2 = TimeZoneInfo.ConvertTime(tokyo, tokyoTZ, estTZ); // 変換方法③ : システム ID を使ってタイムゾーン間を直接変換する場合 DateTime est3 = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(tokyo, "Tokyo Standard Time", "Eastern Standard Time"); // 2007/11/20 00:06:09 (EST) Console.WriteLine("東京 : " + tokyo.ToString()); Console.WriteLine("UTC : " + utc.ToString()); Console.WriteLine("EST : " + est1.ToString() + " 夏時間 = " + est1.IsDaylightSavingTime()); C# OS の持つ一意識別名を 利用する
  • 46. p.46 時差の取り扱い方 ◼ (参考) .NET Framework 3.5 以前の場合  .NET Framework 2.0, 3.0 において、任意のタイムゾーンの情報を 取得したり、時差補正を行うためには、以下の 2 つの方法がある ◼ 3rd party 製などのライブラリを利用する方法 ◼ OS のレジストリからデータを読み取るライブラリを作成する方法  以下を参照するとよい ◼ http://blogs.msdn.com/bclteam/archive/2006/04/03/567119.aspx ◼ http://www.gotdotnet.com/Community/UserSamples/Details.aspx?S ampleGuid=0C9E8F33-7214-4222-B992-D248D107652F