この記事の英語版を表示するには、[英語] のチェック ボックスをオンにしてください。また、テキストにマウス ポインターを合わせると、ポップアップ ウィンドウに英語のテキストを表示することもできます。
翻訳
英語

DateTime と DateTimeOffset 間の変換

 

DateTimeOffset 構造体は DateTime 構造体と比較してタイム ゾーンへの対応の程度が高くなっていますが、メソッドの呼び出しでは DateTime パラメーターを使用するのが一般的です。  このため、DateTimeOffsetDateTime との間で値を変換する機能は、特に重要になります。  ここでは、タイム ゾーン情報を可能な限り保持しながら、これらの変換を実行する方法について説明します。  

System_CAPS_noteメモ

DateTime 型と DateTimeOffset 型には、タイム ゾーンで時刻を表すときにいくつかの制限事項があります。   Kind プロパティを使用すると、DateTime は世界協定時刻 (UTC: Coordinated Universal Time) とシステムのローカル タイム ゾーンのみを反映できます。   DateTimeOffset は、UTC からの時刻のオフセットを反映しますが、そのオフセットが属する実際のタイム ゾーンは反映しません。  時刻の値とタイム ゾーンのサポートの詳細については、「DateTime、DateTimeOffset、TimeSpan、および TimeZoneInfo の使い分け」を参照してください。  

DateTimeOffset 構造体は、大部分の変換処理に適する、DateTime から DateTimeOffset への変換を実行するための方法を 2 つ提供します。これらはどちらも同等の効果があります。

UTC およびローカルの DateTime 値では、結果として出力された DateTimeOffset 値の Offset プロパティに、UTC またはローカル タイム ゾーン オフセットが正確に反映されます。  たとえば、次に示すコードでは、UTC 時刻を同等の DateTimeOffset 値に変換します。  

DateTime utcTime1 = new DateTime(2008, 6, 19, 7, 0, 0);
utcTime1 = DateTime.SpecifyKind(utcTime1, DateTimeKind.Utc);
DateTimeOffset utcTime2 = utcTime1;
Console.WriteLine("Converted {0} {1} to a DateTimeOffset value of {2}", 
                  utcTime1, 
                  utcTime1.Kind.ToString(), 
                  utcTime2);
// This example displays the following output to the console:
//    Converted 6/19/2008 7:00:00 AM Utc to a DateTimeOffset value of 6/19/2008 7:00:00 AM +00:00                        

この場合、utcTime2 変数のオフセットは 00:00 です。  同様に、次に示すコードでは、ローカル タイムを同等の DateTimeOffset 値に変換します。  

DateTime localTime1 = new DateTime(2008, 6, 19, 7, 0, 0);
localTime1 = DateTime.SpecifyKind(localTime1, DateTimeKind.Local);
DateTimeOffset localTime2 = localTime1;
Console.WriteLine("Converted {0} {1} to a DateTimeOffset value of {2}", 
                  localTime1, 
                  localTime1.Kind.ToString(), 
                  localTime2);
// This example displays the following output to the console:
//    Converted 6/19/2008 7:00:00 AM Local to a DateTimeOffset value of 6/19/2008 7:00:00 AM -07:00

ただし、DateTime 値 (Kind プロパティが DateTimeKind.Unspecified) である場合は、これらの 2 つの変換メソッドにより、オフセットにローカル タイム ゾーンが設定された DateTimeOffset 値が生成されます。  これは米国の太平洋標準時タイム ゾーンで実行するには、次の例に示します。  

DateTime time1 = new DateTime(2008, 6, 19, 7, 0, 0);  // Kind is DateTimeKind.Unspecified
DateTimeOffset time2 = time1;
Console.WriteLine("Converted {0} {1} to a DateTimeOffset value of {2}", 
                  time1, 
                  time1.Kind.ToString(), 
                  time2);
// This example displays the following output to the console:
//    Converted 6/19/2008 7:00:00 AM Unspecified to a DateTimeOffset value of 6/19/2008 7:00:00 AM -07:00

DateTime 値がローカル タイム ゾーンでも UTC でもない日付と時刻を反映する場合は、その値を DateTimeOffset 値に変換し、オーバーロードされた DateTimeOffset コンストラクターを呼び出すことによって、タイム ゾーン情報を保持できます。  たとえば、中部標準時を反映する DateTimeOffset オブジェクトをインスタンス化する例を次に示します。  

DateTime time1 = new DateTime(2008, 6, 19, 7, 0, 0);     // Kind is DateTimeKind.Unspecified
try
{
   DateTimeOffset time2 = new DateTimeOffset(time1, 
                  TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time").GetUtcOffset(time1)); 
   Console.WriteLine("Converted {0} {1} to a DateTime value of {2}", 
                     time1, 
                     time1.Kind.ToString(), 
                     time2);
}
// Handle exception if time zone is not defined in registry
catch (TimeZoneNotFoundException)
{
   Console.WriteLine("Unable to identify target time zone for conversion.");
}
// This example displays the following output to the console:
//    Converted 6/19/2008 7:00:00 AM Unspecified to a DateTime value of 6/19/2008 7:00:00 AM -05:00

時刻の対応するタイム ゾーンの TimeZoneInfo.GetUtcOffset(DateTime) メソッドを呼び出して、コンストラクター オーバーロードに対する 2 番目のパラメーターである TimeSpan オブジェクト (UTC からの時刻のオフセットを表す) を取得する必要があります。  このメソッドの唯一のパラメーターは、変換される日付と時刻を表す DateTime 値です。  夏時間をサポートするタイム ゾーンである場合にこのパラメーターを使用すると、メソッドによって特定の日付と時刻に対する適切なオフセットを決定できます。  

DateTime プロパティは、一般に DateTimeOffset から DateTime への変換を実行するときに使用されます。  ただし、次の例に示すように、Kind プロパティが Unspecified である DateTime 値を返します。  

DateTime baseTime = new DateTime(2008, 6, 19, 7, 0, 0);
DateTimeOffset sourceTime;
DateTime targetTime;

// Convert UTC to DateTime value
sourceTime = new DateTimeOffset(baseTime, TimeSpan.Zero);
targetTime = sourceTime.DateTime;
Console.WriteLine("{0} converts to {1} {2}", 
                  sourceTime, 
                  targetTime, 
                  targetTime.Kind.ToString());

// Convert local time to DateTime value
sourceTime = new DateTimeOffset(baseTime, 
                                TimeZoneInfo.Local.GetUtcOffset(baseTime));
targetTime = sourceTime.DateTime;
Console.WriteLine("{0} converts to {1} {2}", 
                  sourceTime, 
                  targetTime, 
                  targetTime.Kind.ToString());

// Convert Central Standard Time to a DateTime value
try
{
   TimeSpan offset = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time").GetUtcOffset(baseTime);
   sourceTime = new DateTimeOffset(baseTime, offset);
   targetTime = sourceTime.DateTime;
   Console.WriteLine("{0} converts to {1} {2}", 
                     sourceTime, 
                     targetTime, 
                     targetTime.Kind.ToString());
}
catch (TimeZoneNotFoundException)
{
   Console.WriteLine("Unable to create DateTimeOffset based on U.S. Central Standard Time.");
} 
// This example displays the following output to the console:
//    6/19/2008 7:00:00 AM +00:00 converts to 6/19/2008 7:00:00 AM Unspecified
//    6/19/2008 7:00:00 AM -07:00 converts to 6/19/2008 7:00:00 AM Unspecified
//    6/19/2008 7:00:00 AM -05:00 converts to 6/19/2008 7:00:00 AM Unspecified                       

これは、DateTime プロパティが設定された状態で変換を行うと、UTC に対する DateTimeOffset 値の関係が削除されることを意味します。  これは、UTC 時刻またはシステムの現地時刻に対応する DateTimeOffset 値に影響します。その理由は、DateTime 構造体が反映するのは Kind プロパティに設定されている 2 つのタイム ゾーンだけであるからです。  

タイム ゾーン情報を可能な限り保持しながら DateTimeOffset から DateTime 値への変換を行うためには、DateTimeOffset.UtcDateTime プロパティと DateTimeOffset.LocalDateTime プロパティを使用します。

変換後の DateTime 値が UTC 時刻であることを確認するには、DateTimeOffset.UtcDateTime プロパティの値を取得します。  これは、DateTime プロパティと 2 つの点で異なります。  

  • DateTime 値を返します。このとき、Kind プロパティは Utc に設定されています。

  • Offset プロパティの値が TimeSpan.Zero ではない場合、時刻を UTC に変換します。

System_CAPS_noteメモ

変換後の DateTime 値が特定の時刻を明確に示すことが必要なアプリケーションでは、DateTimeOffset.UtcDateTime プロパティを使用してすべての DateTimeOffsetDateTime に変換する処理を行うことを検討してください。

次のコード例は、UtcDateTime プロパティを使用して、DateTimeOffset 値 (オフセットは TimeSpan.Zero) を DateTime 値に変換します。

DateTimeOffset utcTime1 = new DateTimeOffset(2008, 6, 19, 7, 0, 0, TimeSpan.Zero);
DateTime utcTime2 = utcTime1.UtcDateTime;
Console.WriteLine("{0} converted to {1} {2}", 
                  utcTime1, 
                  utcTime2, 
                  utcTime2.Kind.ToString());
// The example displays the following output to the console:
//   6/19/2008 7:00:00 AM +00:00 converted to 6/19/2008 7:00:00 AM Utc                              

次のコード例は、UtcDateTime プロパティを使用して、DateTimeOffset 値に対してタイム ゾーン変換と型変換の両方を実行します。

DateTimeOffset originalTime = new DateTimeOffset(2008, 6, 19, 7, 0, 0, new TimeSpan(5, 0, 0));
DateTime utcTime = originalTime.UtcDateTime;
Console.WriteLine("{0} converted to {1} {2}", 
                  originalTime, 
                  utcTime, 
                  utcTime.Kind.ToString());
// The example displays the following output to the console:
//       6/19/2008 7:00:00 AM +05:00 converted to 6/19/2008 2:00:00 AM Utc

DateTimeOffset 値が現地時刻を表していることを確認するには、DateTimeOffset.DateTime プロパティによって返される DateTime 値を static (Visual Basic では Shared) SpecifyKind メソッドに渡します。  このメソッドは、最初のパラメーターとして渡された日付と時刻を返しますが、Kind プロパティは 2 番目のパラメーターで指定された値に設定されています。  次のコード例は、SpecifyKind メソッドを使用して、DateTimeOffset 値の変換を行います。この値のオフセットはローカル タイム ゾーンのオフセットに対応します。  

DateTime sourceDate = new DateTime(2008, 6, 19, 7, 0, 0);
DateTimeOffset utcTime1 = new DateTimeOffset(sourceDate, 
                          TimeZoneInfo.Local.GetUtcOffset(sourceDate));
DateTime utcTime2 = utcTime1.DateTime;
if (utcTime1.Offset.Equals(TimeZoneInfo.Local.GetUtcOffset(utcTime1.DateTime))) 
   utcTime2 = DateTime.SpecifyKind(utcTime2, DateTimeKind.Local);

Console.WriteLine("{0} converted to {1} {2}", 
                  utcTime1, 
                  utcTime2, 
                  utcTime2.Kind.ToString());
// The example displays the following output to the console:
//   6/19/2008 7:00:00 AM -07:00 converted to 6/19/2008 7:00:00 AM Local      

DateTimeOffset.LocalDateTime プロパティを使用して、DateTimeOffset 値をローカルな DateTime 値に変換することもできます。  返される DateTime 値の Kind プロパティには、Local が設定されています。  次のコード例は、DateTimeOffset.LocalDateTime プロパティを使用して、DateTimeOffset 値の変換を行います。この値のオフセットはローカル タイム ゾーンのオフセットに対応します。  

DateTime sourceDate = new DateTime(2008, 6, 19, 7, 0, 0);
DateTimeOffset localTime1 = new DateTimeOffset(sourceDate, 
                          TimeZoneInfo.Local.GetUtcOffset(sourceDate));
DateTime localTime2 = localTime1.LocalDateTime;

Console.WriteLine("{0} converted to {1} {2}", 
                  localTime1, 
                  localTime2, 
                  localTime2.Kind.ToString());
// The example displays the following output to the console:
//   6/19/2008 7:00:00 AM -07:00 converted to 6/19/2008 7:00:00 AM Local      

DateTimeOffset.LocalDateTime プロパティを使用して DateTime 値を取得すると、プロパティの get アクセサーは、まず DateTimeOffset 値を UTC に変換し、次に ToLocalTime メソッドを呼び出して現地時刻に変換します。  これは、DateTimeOffset.LocalDateTime プロパティの値を取得して、型変換の実行と同時にタイム ゾーンの変換も実行できることを意味します。  また、変換実行時にはローカル タイム ゾーンの調整規則が適用されることにもなります。  次のコード例は、DateTimeOffset.LocalDateTime プロパティを使用して、型変換とタイム ゾーン変換の両方を実行します。  

DateTimeOffset originalDate;
DateTime localDate;

// Convert time originating in a different time zone
originalDate = new DateTimeOffset(2008, 6, 18, 7, 0, 0, 
                                  new TimeSpan(-5, 0, 0));
localDate = originalDate.LocalDateTime;
Console.WriteLine("{0} converted to {1} {2}", 
                  originalDate, 
                  localDate, 
                  localDate.Kind.ToString());
// Convert time originating in a different time zone 
// so local time zone's adjustment rules are applied
originalDate = new DateTimeOffset(2007, 11, 4, 4, 0, 0, 
                                  new TimeSpan(-5, 0, 0));
localDate = originalDate.LocalDateTime;
Console.WriteLine("{0} converted to {1} {2}", 
                  originalDate, 
                  localDate, 
                  localDate.Kind.ToString());
// The example displays the following output to the console:
//       6/19/2008 7:00:00 AM -05:00 converted to 6/19/2008 5:00:00 AM Local
//       11/4/2007 4:00:00 AM -05:00 converted to 11/4/2007 1:00:00 AM Local

次の例では、ConvertFromDateTimeOffset というメソッドを定義します。このメソッドは、DateTimeOffset 値を DateTime 値に変換します。  そのオフセットに基づいて、DateTimeOffset 値が UTC 時刻、現地時刻、その他の時刻のいずれであるかを判断し、それに応じて、返される日付と時刻の値の Kind プロパティを定義します。  

static DateTime ConvertFromDateTimeOffset(DateTimeOffset dateTime)
{
   if (dateTime.Offset.Equals(TimeSpan.Zero))
      return dateTime.UtcDateTime;
   else if (dateTime.Offset.Equals(TimeZoneInfo.Local.GetUtcOffset(dateTime.DateTime)))
      return DateTime.SpecifyKind(dateTime.DateTime, DateTimeKind.Local);
   else
      return dateTime.DateTime;   
}

次の例では、米国の中部標準時ゾーンの UTC 時刻、現地時間と時刻を表す DateTimeOffset 値を変換するに ConvertFromDateTimeOffset のメソッドを呼び出します。

DateTime timeComponent = new DateTime(2008, 6, 19, 7, 0, 0);
DateTime returnedDate; 

// Convert UTC time
DateTimeOffset utcTime = new DateTimeOffset(timeComponent, TimeSpan.Zero);
returnedDate = ConvertFromDateTimeOffset(utcTime); 
Console.WriteLine("{0} converted to {1} {2}", 
                  utcTime, 
                  returnedDate, 
                  returnedDate.Kind.ToString());

// Convert local time
DateTimeOffset localTime = new DateTimeOffset(timeComponent, 
                           TimeZoneInfo.Local.GetUtcOffset(timeComponent)); 
returnedDate = ConvertFromDateTimeOffset(localTime);                                          
Console.WriteLine("{0} converted to {1} {2}", 
                  localTime, 
                  returnedDate, 
                  returnedDate.Kind.ToString());

// Convert Central Standard Time
DateTimeOffset cstTime = new DateTimeOffset(timeComponent, 
               TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time").GetUtcOffset(timeComponent));
returnedDate = ConvertFromDateTimeOffset(cstTime);
Console.WriteLine("{0} converted to {1} {2}", 
                  cstTime, 
                  returnedDate, 
                  returnedDate.Kind.ToString());
// The example displays the following output to the console:
//    6/19/2008 7:00:00 AM +00:00 converted to 6/19/2008 7:00:00 AM Utc
//    6/19/2008 7:00:00 AM -07:00 converted to 6/19/2008 7:00:00 AM Local
//    6/19/2008 7:00:00 AM -05:00 converted to 6/19/2008 7:00:00 AM Unspecified

このコードでは、アプリケーションおよび日付と時刻の値のソースに応じて、必ずしも常に有効ではない 2 つの前提条件が想定されます。

  • オフセットが TimeSpan.Zero に設定されている日付と時刻の値は、UTC 時刻を表すことを前提とします。  実際には、UTC は特定のタイム ゾーンの時刻ではありませんが、この時刻を基準として世界のタイム ゾーンの時刻が標準化されます。  タイム ゾーンには、Zero のオフセットを設定することもできます。  

  • ローカル タイム ゾーンのオフセットに等しいオフセットが設定された日付と時刻は、ローカル タイム ゾーンを表すことを前提とします。  日付と時刻の値と元のタイム ゾーンとの関連付けが解除されていることが理由となって、この前提条件に該当しないことがあります。日付と時刻には、同じオフセットが設定された他のタイム ゾーンの日付と時刻を設定できます。  

表示: