ここではSystem.DateTime構造体と比較することによって、System.DateTimeOffset構造体の使い方を説明します。DateTime構造体については説明しませんので、DateTime構造体に関する基本的な知識がないという方は、「指定した日時のDateTimeオブジェクトを作成する」や「日時(DateTimeオブジェクト)の情報を取得する」をご覧ください。
DateTimeOffset構造体は.NET Framework 2.0 SP1から追加された型で、DateTime構造体と同様に日時を表す型です。DateTimeとの違いは、DateTimeOffsetがUTC(世界協定時刻)との時差(オフセット)をOffsetプロパティに保持している点です。その代わりにDateTimeがKindプロパティとして保持している情報は持っていません。
例えばDateTimeOffsetが表現している日時がUTCの場合、Offsetプロパティは 00:00:00 です。日本時間の場合、Offsetプロパティは 09:00:00 です。
DateTimeオブジェクトのKindプロパティがUtcの時は、そのDateTimeオブジェクトが表している日時は明確です。しかしKindプロパティがLocalやUnspecifiedの時は、一体どこのタイムゾーンの時刻なのか分かりませんので、そのDateTimeオブジェクトが表している日時は不明確です。
DateTimeOffsetは、この問題を解消します。DateTimeOffsetはUTCとのオフセットを保持していますので、DateTimeOffsetオブジェクトが表現している日時が現地時間(ローカル時刻)だとしても、明確な日時を示すことができます。つまり、現地時間を表現する時、明確な日時を表現できるのがDateTimeOffsetです。
ただし、DateTimeOffsetはUTCとの時差を保持しているだけで、タイムゾーンの情報は持っていませんので、サマータイムのように特定の時期だけ時差が変わってしまうケースにまでは対応していません。
DateTimeOffsetオブジェクトを作成する方法は、「指定した日時のDateTimeオブジェクトを作成する」で説明しているDateTimeの方法とほぼ同じです。ここでは主な方法を幾つか紹介します。
コンストラクタを呼び出してDateTimeOffsetオブジェクトを作成する場合、UTCとのオフセットをTimeSpanで指定しなければならない点がDateTimeと異なります。なおTimeSpanについては、「TimeSpanオブジェクトを作成する、情報を取得する」で説明しています。
'2000年8月1日 13時30分00秒 +9時間 を表すDateTimeOffsetオブジェクトを作成する Dim dto1 As New DateTimeOffset(2000, 8, 1, 13, 30, 0, New TimeSpan(9, 0, 0))
//2000年8月1日 13時30分00秒 +9時間 を表すDateTimeOffsetオブジェクトを作成する DateTimeOffset dto1 = new DateTimeOffset(2000, 8, 1, 13, 30, 0, new TimeSpan(9, 0, 0));
既存のDateTimeオブジェクトからDateTimeOffsetオブジェクトを作成することもできます。この場合はオフセットを指定しなくてもOKです。オフセットを指定しなかった場合、DateTimeのKindプロパティがUtcならばオフセットが0になり、それ以外ならばオフセットがローカルコンピュータのタイムゾーンのオフセット(日本の場合は、+9時間)になります。
DateTimeのKindプロパティがUnspecifiedの時は、オフセットに自由な値を指定することもできます。
Dim dtUtc As New DateTime(2000, 9, 24, 15, 30, 0, DateTimeKind.Utc) Dim dtLocal As New DateTime(2000, 9, 24, 15, 30, 0, DateTimeKind.Local) 'KindがUtcのDateTimeからDateTimeOffsetオブジェクトを作成する Dim dto4 As New DateTimeOffset(dtUtc) '2000/09/24 15:30:00 +00:00 'KindがLocalのDateTimeからDateTimeOffsetオブジェクトを作成する Dim dto5 As New DateTimeOffset(dtLocal) '2000/09/24 15:30:00 +09:00 'オフセットを指定してDateTimeOffsetオブジェクトを作成する 'KindがUtcのDateTimeの時はオフセットが0でなければならないので、例外が発生する 'Dim dto6 As New DateTimeOffset(dtUtc, New TimeSpan(-5, 0, 0)) 'KindをUnspecifiedに変換すれば、自由なオフセットを指定できる Dim dtUnspecified As DateTime = DateTime.SpecifyKind(dtUtc, DateTimeKind.Unspecified) Dim dto7 As New DateTimeOffset(dtUnspecified, New TimeSpan(-5, 0, 0)) '2000/09/24 15:30:00 -05:00
DateTime dtUtc = new DateTime(2000, 9, 24, 15, 30, 0, DateTimeKind.Utc); DateTime dtLocal = new DateTime(2000, 9, 24, 15, 30, 0, DateTimeKind.Local); //KindがUtcのDateTimeからDateTimeOffsetオブジェクトを作成する DateTimeOffset dto4 = new DateTimeOffset(dtUtc); //2000/09/24 15:30:00 +00:00 //KindがLocalのDateTimeからDateTimeOffsetオブジェクトを作成する DateTimeOffset dto5 = new DateTimeOffset(dtLocal); //2000/09/24 15:30:00 +09:00 //オフセットを指定してDateTimeOffsetオブジェクトを作成する //KindがUtcのDateTimeの時はオフセットが0でなければならないので、例外が発生する //DateTimeOffset dto6 = new DateTimeOffset(dtUtc, new TimeSpan(-5, 0, 0)); //KindをUnspecifiedに変換すれば、自由なオフセットを指定できる DateTime dtUnspecified = DateTime.SpecifyKind(dtUtc, DateTimeKind.Unspecified); DateTimeOffset dto7 = new DateTimeOffset(dtUnspecified, new TimeSpan(-5, 0, 0)); //2000/09/24 15:30:00 -05:00
DateTimeをDateTimeOffsetを変更するならば、上記のようにわざわざコンストラクタを呼びださなくても、暗黙的に変換することができます。この時のオフセットは、上で説明したオフセットを指定しないでDateTimeオブジェクトからDateTimeOffsetオブジェクトを作成した場合と同じになります。
Dim dtUtc As New DateTime(2000, 9, 24, 15, 30, 0, DateTimeKind.Utc) Dim dtLocal As New DateTime(2000, 9, 24, 15, 30, 0, DateTimeKind.Local) 'DateTimeをDateTimeOffsetに暗黙の型変換をする Dim dto8 As DateTimeOffset = dtUtc '2000/09/24 15:30:00 +00:00 Dim dto9 As DateTimeOffset = dtLocal '2000/09/24 15:30:00 +09:00
DateTime dtUtc = new DateTime(2000, 9, 24, 15, 30, 0, DateTimeKind.Utc); DateTime dtLocal = new DateTime(2000, 9, 24, 15, 30, 0, DateTimeKind.Local); //DateTimeをDateTimeOffsetに暗黙の型変換をする DateTimeOffset dto8 = dtUtc; //2000/09/24 15:30:00 +00:00 DateTimeOffset dto9 = dtLocal; //2000/09/24 15:30:00 +09:00
「2000/09/24 15:30:00 +09:00」のような文字列をDateTimeOffsetオブジェクトに変換することも出来ます。その方法は、「日時を表す文字列をDateTimeオブジェクトに変換する」で説明している方法と同じです。
DateTimeOffset.Parseメソッドを使って、文字列をDateTimeOffsetオブジェクトに変換する簡単な例を幾つか紹介します。詳しくは、「日時を表す文字列をDateTimeオブジェクトに変換する」をご覧ください。
'文字列をDateTimeOffsetに変換する Dim s1 As String = "2000/09/24 15:30:00 +09:00" Dim dto10 As DateTimeOffset = DateTimeOffset.Parse(s1) '2000/09/24 15:30:00 +09:00 'オフセットの記述がない文字列をDateTimeOffsetに変換する Dim s2 As String = "2000/09/24 15:30:00" Dim dto11 As DateTimeOffset = DateTimeOffset.Parse(s2) '2000/09/24 15:30:00 +09:00
//文字列をDateTimeOffsetに変換する string s1 = "2000/09/24 15:30:00 +09:00"; DateTimeOffset dto10 = DateTimeOffset.Parse(s1); //2000/09/24 15:30:00 +09:00 //オフセットの記述がない文字列をDateTimeOffsetに変換する string s2 = "2000/09/24 15:30:00"; DateTimeOffset dto11 = DateTimeOffset.Parse(s2); //2000/09/24 15:30:00 +09:00
DateTimeOffsetの計算はDateTimeと同じようにできます。メソッドもDateTimeと同じものが用意されています。DateTimeの計算については、「日時、時間の計算をする」で説明しています。
DateTimeの計算とDateTimeOffsetの計算で異なるのは、DateTimeの計算ではKindプロパティが考慮されないのに対して、DateTimeOffsetの計算ではオフセットの値が考慮される点です。
下の例では、日時が同じでオフセットが9時間違う2つのDateTimeOffsetを作成して、引き算しています。結果は、9時間となります。
'オフセットが9時間異なる2つのDateTimeOffsetを作成する Dim dto1 As New DateTimeOffset(2000, 9, 1, 0, 0, 0, TimeSpan.FromHours(0)) Dim dto2 As New DateTimeOffset(2000, 9, 1, 0, 0, 0, TimeSpan.FromHours(9)) '2つの日時を引く Dim ts1 As TimeSpan = dto1 - dto2 Console.WriteLine(ts1) '09:00:00
//オフセットが9時間異なる2つのDateTimeOffsetを作成する DateTimeOffset dto1 = new DateTimeOffset(2000, 9, 1, 0, 0, 0, TimeSpan.FromHours(0)); DateTimeOffset dto2 = new DateTimeOffset(2000, 9, 1, 0, 0, 0, TimeSpan.FromHours(9)); //2つの日時を引く TimeSpan ts1 = dto1 - dto2; Console.WriteLine(ts1); //09:00:00
DateTimeOffsetオブジェクトをUTCに変換するには、ToUniversalTimeメソッドを使います。ToUniversalTimeメソッドは、日時をオフセット分減らして、Offsetプロパティを 00:00:00 としたDateTimeOffsetオブジェクトを返します。
DateTimeOffsetオブジェクトをローカル時刻(ローカルコンピュータのタイムゾーンでの時刻)に変換するには、ToLocalTimeメソッドを使います。ToLocalTimeメソッドは、日時をUTCに変換した後、ローカルコンピュータのタイムゾーンのオフセット値を加えて、さらにそれをOffsetプロパティとしたDateTimeOffsetオブジェクトを返します。
以下の例では、オフセットが-5時間のDateTimeOffsetオブジェクトを作成し、そのUTCとローカル時刻(日本時間)を取得しています。
Dim dt As New DateTime(2000, 9, 24, 15, 30, 0) 'オフセットを-5時間としてDateTimeOffsetを作成する Dim dto As New DateTimeOffset(dt, New TimeSpan(-5, 0, 0)) Console.WriteLine(dto) '2000/09/24 15:30:00 -05:00 'UTCに変換する Dim utcTime As DateTimeOffset = dto.ToUniversalTime() Console.WriteLine(utcTime) '2000/09/24 20:30:00 +00:00 'ローカル時刻(日本時間)に変換する Dim localTime As DateTimeOffset = dto.ToLocalTime() Console.WriteLine(localTime) '2000/09/25 5:30:00 +09:00
DateTime dt = new DateTime(2000, 9, 24, 15, 30, 0); //オフセットを-5時間としてDateTimeOffsetを作成する DateTimeOffset dto = new DateTimeOffset(dt, new TimeSpan(-5, 0, 0)); Console.WriteLine(dto); //2000/09/24 15:30:00 -05:00 //UTCに変換する DateTimeOffset utcTime = dto.ToUniversalTime(); Console.WriteLine(utcTime); //2000/09/24 20:30:00 +00:00 //ローカル時刻(日本時間)に変換する DateTimeOffset localTime = dto.ToLocalTime(); Console.WriteLine(localTime); //2000/09/25 5:30:00 +09:00
これらのメソッド以外に、DateTimeOffsetオブジェクトが表している日時をUTCやローカル時刻で取得できるプロパティも用意されています。
UtcDateTimeプロパティによって、UTCをDateTimeオブジェクトで取得できます。また、LocalDateTimeプロパティによって、ローカル時刻をDateTimeオブジェクトで取得できます。
DateTimeOffset構造体のプロパティの内、DateTimeにはないプロパティを表にまとめると、以下のようになります。
プロパティ名 | 説明 | プロパティ値の型 | プロパティ値の範囲 |
---|---|---|---|
Offset | UTCからの時差を取得する。 | TimeSpan | -14:00:00~14:00:00 |
DateTime | Offsetプロパティを無視した日時の部分だけをDateTimeで取得する。DateTimeOffsetが「02/9/30 13:00 +9:00」ならば、「02/9/30 13:00」となる。DateTimeUtcプロパティにOffsetプロパティを足した値。DateTimeのKindプロパティはDateTimeKind.Unspecifiedになる。 | DateTime | |
LocalDateTime | 現地時刻をDateTimeで取得する。UtcDateTimeプロパティの値をローカルコンピュータの現地時刻に変換する。DateTimeのKindプロパティはDateTimeKind.Localになる。 | DateTime | |
UtcDateTime | UTCをDateTimeで取得する。DateTimeプロパティからOffsetプロパティを引いた値。DateTimeのKindプロパティはDateTimeKind.Utcになる。 | DateTime | |
UtcTicks | UTCのタイマ刻み数を取得する。DateTimeOffset.UtcDateTime.Ticksと同じ。 | Int64 |
以下に、DateTimeOffsetのプロパティによってUTCやローカル時刻を取得する例を示します。
'オフセットが-5時間のDateTimeOffsetを作成する Dim dto As New DateTimeOffset(2000, 9, 24, 15, 30, 0, _ TimeSpan.FromHours(-5)) Console.WriteLine(dto) '2000/09/24 15:30:00 -05:00 'UTCを取得する Dim utcTime As DateTime = dto.UtcDateTime Console.WriteLine("{0} {1}", utcTime, utcTime.Kind) '2000/09/24 20:30:00 Utc 'ローカル時刻(日本時間)を取得する Dim localTime As DateTime = dto.LocalDateTime Console.WriteLine("{0} {1}", localTime, localTime.Kind) '2000/09/25 5:30:00 Local 'DateTimeオブジェクトでdtoが示す日時を取得する Dim dt As DateTime = dto.DateTime Console.WriteLine("{0} {1}", dt, dt.Kind) '2000/09/24 15:30:00 Unspecified
//オフセットが-5時間のDateTimeOffsetを作成する DateTimeOffset dto = new DateTimeOffset(2000, 9, 24, 15, 30, 0, TimeSpan.FromHours(-5)); Console.WriteLine(dto); //2000/09/24 15:30:00 -05:00 //UTCを取得する DateTime utcTime = dto.UtcDateTime; Console.WriteLine("{0} {1}", utcTime, utcTime.Kind); //2000/09/24 20:30:00 Utc //ローカル時刻(日本時間)を取得する DateTime localTime = dto.LocalDateTime; Console.WriteLine("{0} {1}", localTime, localTime.Kind); //2000/09/25 5:30:00 Local //DateTimeオブジェクトでdtoが示す日時を取得する DateTime dt = dto.DateTime; Console.WriteLine("{0} {1}", dt, dt.Kind); //2000/09/24 15:30:00 Unspecified
DateTimeOffsetオブジェクトを任意のタイムゾーンのローカル時刻に変換するには、TimeZoneInfo.ConvertTimeメソッドやTimeZoneInfo.ConvertTimeBySystemTimeZoneIdメソッドを使います。これらのメソッドについては、「ローカル時刻を世界協定時刻(UTC)に変換する」で説明しています。
注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。