.NETでは、もうひとつ日時を表すデータ型としてDateTimeOffset構造体も用意されています。 これは.NET Framework 3.5から導入された構造体です。

DateTimeOffsetはDateTimeとよく似た構造体で、DateTimeにオフセット情報(UTCからの時差)を持たせたものに相当します。 つまり、DateTimeOffsetは日付と時刻に加え、オフセット情報をひとまとめにして扱います。 DateTimeにおける時刻の種類(Kindプロパティ)の代わりとして、DateTimeOffsetではオフセット情報(Offsetプロパティ)が存在すると言うこともできます。

これにより、DateTimeではローカルまたはUTCの日時のみしか扱えないのに対して、DateTimeOffsetでは任意のタイムゾーンの日時が扱えるという違いがあります。

DateTimeOffset構造体
using System;

class Sample {
  static void Main()
  {
    // 2013年4月1日 午後3時0分30秒 (ローカル時刻)
    var a = new DateTime(2013, 4, 1, 15, 0, 30);

    // 2013年4月1日 午後3時0分30秒 (UTC)
    var b = new DateTimeOffset(2013, 4, 1, 15, 0, 30, TimeSpan.Zero);

    // 2013年4月1日 午後3時0分30秒 (UTC+9)
    var c = new DateTimeOffset(2013, 4, 1, 15, 0, 30, new TimeSpan(9, 0, 0));

    // 2013年4月1日 午後3時0分30秒 (UTC-5)
    var d = new DateTimeOffset(a, new TimeSpan(-5, 0, 0));
  }
}

DateTimeでは常にローカル時刻もしくはUTCのどちらかに変換して日時を格納するためオフセット値は消失しますが、DateTimeOffsetではオフセット値を個別に格納するようになっているため、オフセット情報を消失することなく日時を格納することが出来ます。

例えば、実行環境が日本標準時に設定されている環境において、東部標準時での時刻をDateTimeに格納しようとする場合を考えます。 この場合DateTimeでは、ローカル時刻である日本標準時か、もしくはUTCのどちらかに変換して格納しなければならないため、DateTimeに格納する際に「時刻は東部標準時のものである」という情報は失われますが、DateTimeOffsetを使えばオフセット値を維持したまま格納することができるため、「時刻は東部標準時である」という情報は維持されます。

ただ、厳密にいえばDateTimeOffsetに格納されるのはオフセット値のみであり、具体的にどのタイムゾーンの日時かといった情報ではありません。 そのため、例えばUTC+9である日本標準時の日時と、同じくUTC+9である韓国標準時の日時はまったく同一の値として扱われる事になります。 タイムゾーンに関するより高度な操作が必要な場合はTimeZoneInfoクラスを使う必要があります。