TimeZoneInfoクラスを利用して、Windowsが保持しているタイムゾーン情報を取得し、そこから時差を求める方法を解説する。
対象:.NET 3.5以降
時差を扱うプログラムではDateTimeOffset構造体を使えばよい(「.NET TIPS:DateTimeとDateTimeOffsetの違いとは?[C#、VB]」)。だが、その時差はどのようにして与えればよいのだろうか? プログラム側にテーブルを持ってもよいが、夏時間があると厄介になる。夏時間の開始日時/終了日時もテーブルに持たなければならないからだ。ところで、Windowsは世界各地のタイムゾーンの情報を持っている。タイムゾーン情報には夏時間の情報も含まれているので、その情報が利用できれば簡単にプログラミングできるだろう。本稿では、Windowsが持っているタイムゾーン情報から時差を求める方法を解説する。
Windowsシステムが持っているタイムゾーンの情報は、TimeZoneInfoクラス(System名前空間)を通じて利用できる。時差を取得するには、まずタイムゾーンのID文字列をTimeZoneInfoクラスのFindSystemTimeZoneById静的メソッドに与えてTimeZoneInfoオブジェクトを取得し、次に引数に時差を求めたい時刻を指定してGetUtcOffsetメソッドを呼び出せばよい(次のコード)。夏時間の調整も含めて、UTC(世界協定時)からの時差を正しく返してくれる。
// 夏時間のあるTimeZoneInfoオブジェクト、例としてPST(太平洋標準時)の情報を取得する
var tzPst = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
// 夏時間終了1秒前(現地時間ではAM1:59:59)
var u1 = new DateTimeOffset(2015, 11, 1, 8, 59, 59, TimeSpan.Zero);
var o1 = tzPst.GetUtcOffset(u1);
Console.WriteLine("Offset at {0:yyyy/MM/dd HH:mm}(UTC) = {1} hours", u1, o1.Hours);
// 出力: Offset at 2015/11/01 08:59(UTC) = -7 hours
// 夏時間終了直後(現地時間ではAM1:00:00)
var u2 = new DateTimeOffset(2015, 11, 1, 9, 0, 0, TimeSpan.Zero);
var o2 = tzPst.GetUtcOffset(u2);
Console.WriteLine("Offset at {0:yyyy/MM/dd HH:mm}(UTC) = {1} hours", u2, o2.Hours);
// 出力: Offset at 2015/11/01 09:00(UTC) = -8 hours
' 夏時間のあるTimeZoneInfoオブジェクト、例としてPST(太平洋標準時)の情報を取得する
Dim tzPst = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time")
' 夏時間終了1秒前(現地時間ではAM1:59:59)
Dim u1 = New DateTimeOffset(2015, 11, 1, 8, 59, 59, TimeSpan.Zero)
Dim o1 = tzPst.GetUtcOffset(u1)
Console.WriteLine("Offset at {0:yyyy/MM/dd HH:mm}(UTC) = {1} hours", u1, o1.Hours)
' 出力: Offset at 2015/11/01 08:59(UTC) = -7 hours
' 夏時間終了直後(現地時間ではAM1:00:00)
Dim u2 = New DateTimeOffset(2015, 11, 1, 9, 0, 0, TimeSpan.Zero)
Dim o2 = tzPst.GetUtcOffset(u2)
Console.WriteLine("Offset at {0:yyyy/MM/dd HH:mm}(UTC) = {1} hours", u2, o2.Hours)
' 出力: Offset at 2015/11/01 09:00(UTC) = -8 hours
Windowsシステムが持っているタイムゾーン情報の全ては、TimeZoneInfoクラスのGetSystemTimeZones静的メソッドで取得できる(次のコードと画像)。結果はTimeZoneInfoオブジェクトのコレクションである。そのTimeZoneInfoオブジェクトのIdプロパティを、先に示したFindSystemTimeZoneById静的メソッドの引数などとして使うのである。以下の画面キャプチャではスクロールアウトしてしまっているが、上で示した「Pacific Standard Time」(PST)もタイムゾーンを示すIdであり、太平洋標準時(アメリカ西海岸で使われている標準時)を表している。
// システムに登録されているタイムゾーン情報を列挙する
var tzInfoList = TimeZoneInfo.GetSystemTimeZones();
foreach (var tzInfo in tzInfoList)
Console.WriteLine("{0}: {1}",
tzInfo.DisplayName, tzInfo.Id);
' システムに登録されているタイムゾーン情報を列挙する
Dim tzInfoList = TimeZoneInfo.GetSystemTimeZones()
For Each tzInfo In tzInfoList
Console.WriteLine("{0}: {1}",
tzInfo.DisplayName, tzInfo.Id)
Next
プログラムが実行されているPCに設定されているタイムゾーン情報は、TimeZoneInfoクラスのLocal静的プロパティで得られる(次のコード)。データ入力プログラムなどでは、これを使えば十分なことも多いだろう。
// 日本標準時のタイムゾーン情報を得る
var tzJst = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
// 動作しているPCに設定されているタイムゾーンを得る
var tzLocal = TimeZoneInfo.Local;
if (tzJst.Id == tzLocal.Id)
Console.WriteLine("tzJst equals tzLocal, ID={0}", tzLocal.Id);
// 出力: tzJst equals tzLocal, ID=Tokyo Standard Time
' 日本標準時のタイムゾーン情報を得る
Dim tzJst = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time")
' 動作しているPCに設定されているタイムゾーンを得る
Dim tzLocal = TimeZoneInfo.Local
If (tzJst.Id = tzLocal.Id) Then
Console.WriteLine("tzJst equals tzLocal, ID={0}", tzLocal.Id)
End If
' 出力: tzJst equals tzLocal, ID=Tokyo Standard Time
Windowsシステムが持っているタイムゾーンの情報を利用するには、TimeZoneInfoクラスを使う。夏時間の調整も自動的に行ってくれる。
なお、Windowsランタイムアプリ/Windows 10のユニバーサルWindowsアプリではTimeZoneInfoクラスが使えない。その対策は「WinRT/Metro TIPS:夏時間を考慮して日時を変換するには?[Win 8/WP 8]」をご覧いただきたい。
利用可能バージョン: .NET Framework 3.5以降
カテゴリ: クラスライブラリ 処理対象:日付と時刻
使用ライブラリ: TimeZoneInfoクラス(System名前空間)
関連TIPS: DateTimeとDateTimeOffsetの違いとは?[C#、VB]
関連TIPS: UTC(世界協定時)を取得するには?[C#、VB]
Copyright© Digital Advantage Corp. All Rights Reserved.