構造体は、構造体よりもタイム ゾーンの認識度が高くなりますが、パラメーターはメソッド呼び出しでより一般的に使用されます。 このアプローチにより、 値を 値に変換する機能、およびその逆の変換が重要になります。 この記事では、可能な限り多くのタイム ゾーン情報を保持する方法で、これらの変換を実行する方法について説明します。
注
タイム ゾーンで時刻を表す場合、 と の両方の型にはいくつかの制限があります。 プロパティを使用すると、は協定世界時 (UTC) とシステムのローカル タイム ゾーンのみを反映できます。 は UTC からの時刻のオフセットを反映しますが、そのオフセットが属する実際のタイム ゾーンは反映されません。 時間値とタイム ゾーンのサポートの詳細については、「 DateTime、DateTimeOffset、TimeSpan、TimeZoneInfo の選択」を参照してください。
DateTime から DateTimeOffset への変換
構造体には、ほとんどの変換に適した方法での変換を実行するための 2 つの同等の方法が提供されています。
コンストラクター。値に基づいて新しい オブジェクトを作成します。
暗黙的な変換演算子。これにより、 オブジェクトに値を割り当てることができます。
UTC 値とローカル 値の場合、結果の値の プロパティには、UTC またはローカル タイム ゾーンオフセットが正確に反映されます。 たとえば、次のコードは UTC 時刻を等価の 値に変換します。
DateTime utcTime1 = new DateTime(2008, 6, 19, 7, 0, 0);
utcTime1 = DateTime.SpecifyKind(utcTime1, DateTimeKind.Utc);
DateTimeOffset utcTime2 = utcTime1;
Console.WriteLine($"Converted {utcTime1} {utcTime1.Kind} to a DateTimeOffset value of {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
Dim utcTime1 As Date = Date.SpecifyKind(#06/19/2008 7:00AM#, _
DateTimeKind.Utc)
Dim utcTime2 As DateTimeOffset = 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
この場合、 変数のオフセットは 00:00 です。 同様に、次のコードはローカル時刻を等価の 値に変換します。 変換は、米国太平洋標準タイム ゾーンで実行されます。
DateTime localTime1 = new DateTime(2008, 6, 19, 7, 0, 0);
localTime1 = DateTime.SpecifyKind(localTime1, DateTimeKind.Local);
DateTimeOffset localTime2 = localTime1;
Console.WriteLine($"Converted {localTime1} {localTime1.Kind} to a DateTimeOffset value of {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
Dim localTime1 As Date = Date.SpecifyKind(#06/19/2008 7:00AM#, DateTimeKind.Local)
Dim localTime2 As DateTimeOffset = 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
ただし、プロパティが特定の値を持つ場合、これら2つの変換メソッドは、現地時間帯のオフセットを持つ値を生成します。 変換を次の例に示します。これは、米国太平洋標準時ゾーンで実行されます。
DateTime time1 = new DateTime(2008, 6, 19, 7, 0, 0); // Kind is DateTimeKind.Unspecified
DateTimeOffset time2 = time1;
Console.WriteLine($"Converted {time1} {time1.Kind} to a DateTimeOffset value of {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
Dim time1 As Date = #06/19/2008 7:00AM# ' Kind is DateTimeKind.Unspecified
Dim time2 As DateTimeOffset = 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
値にローカル タイム ゾーンまたは UTC 以外の日付と時刻が反映されている場合は、オーバーロードされた コンストラクターを呼び出して、値に変換し、そのタイム ゾーン情報を保持できます。 たとえば、次の例では、中央標準時を反映する オブジェクトをインスタンス化します。
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 {time1} {time1.Kind} to a DateTime value of {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
Dim time1 As Date = #06/19/2008 7:00AM# ' Kind is DateTimeKind.Unspecified
Try
Dim time2 As 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 e As TimeZoneNotFoundException
Console.WriteLine("Unable to identify target time zone for conversion.")
End Try
' 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
このコンストラクター オーバーロードの 2 番目のパラメーターは、UTC からの時刻のオフセットを表す オブジェクトです。 時刻の対応するタイム ゾーンの メソッドを呼び出して取得します。 メソッドの単一パラメーターは、変換する日時を表す 値です。 タイム ゾーンで夏時間がサポートされている場合、このパラメーターを使用すると、メソッドはその特定の日付と時刻の適切なオフセットを決定できます。
DateTimeOffset から 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($"{sourceTime} converts to {targetTime} {targetTime.Kind}");
// Convert local time to DateTime value
sourceTime = new DateTimeOffset(baseTime,
TimeZoneInfo.Local.GetUtcOffset(baseTime));
targetTime = sourceTime.DateTime;
Console.WriteLine($"{sourceTime} converts to {targetTime} {targetTime.Kind}");
// 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($"{sourceTime} converts to {targetTime} {targetTime.Kind}");
}
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
Const baseTime As Date = #06/19/2008 7:00AM#
Dim sourceTime As DateTimeOffset
Dim targetTime As Date
' 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
Dim offset As TimeSpan = 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 e As TimeZoneNotFoundException
Console.WriteLine("Unable to create DateTimeOffset based on U.S. Central Standard Time.")
End Try
' 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
前の例では、 値と UTC の関係に関する情報は、 プロパティを使用するときに変換によって失われることを示しています。 この動作は、UTC 時刻またはシステムの現地時刻に対応する 値にも影響します。これは、 構造体には、 プロパティの 2 つのタイム ゾーンのみが反映されるためです。
ある値を別の値に変換する際に、可能な限り多くのタイムゾーン情報を保持するには、
UTC 時刻の変換
変換された 値が UTC 時刻であることを示すために、 プロパティの値を取得できます。 プロパティとは 2 つの点で異なります。
プロパティが指定された値を返します。
プロパティ値が等しくない場合は、時刻を UTC に変換します。
注
アプリケーションで変換された 値が 1 つの時点を明確に識別する必要がある場合は、 プロパティを使用して、すべての から への変換を処理することを検討する必要があります。
次のコードでは、 プロパティを使用して、オフセットが と等しい値を値に変換します。
DateTimeOffset utcTime1 = new DateTimeOffset(2008, 6, 19, 7, 0, 0, TimeSpan.Zero);
DateTime utcTime2 = utcTime1.UtcDateTime;
Console.WriteLine($"{utcTime1} converted to {utcTime2} {utcTime2.Kind}");
// 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
Dim utcTime1 As New DateTimeOffset(#06/19/2008 7:00AM#, TimeSpan.Zero)
Dim utcTime2 As Date = 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
次のコードでは、 プロパティを使用して、 値に対してタイム ゾーン変換と型変換の両方を実行します。
DateTimeOffset originalTime = new DateTimeOffset(2008, 6, 19, 7, 0, 0, new TimeSpan(5, 0, 0));
DateTime utcTime = originalTime.UtcDateTime;
Console.WriteLine($"{originalTime} converted to {utcTime} {utcTime.Kind}");
// 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
Dim originalTime As New DateTimeOffset(#6/19/2008 7:00AM#, _
New TimeSpan(5, 0, 0))
Dim utcTime As Date = 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 値が現地時刻を表していることを示すために、DateTime プロパティによって返される DateTimeOffset.DateTime 値を static (Visual Basic の Shared) SpecifyKind メソッドに渡すことができます。 このメソッドは、最初のパラメーターとして渡された日付と時刻を返しますが、 プロパティを 2 番目のパラメーターで指定された値に設定します。 次のコードでは、オフセットがローカル タイム ゾーンの値に対応する値を変換するときに、 メソッドを使用します。
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($"{utcTime1} converted to {utcTime2} {utcTime2.Kind}");
// 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
Dim sourceDate As Date = #06/19/2008 7:00AM#
Dim utcTime1 As New DateTimeOffset(sourceDate, _
TimeZoneInfo.Local.GetUtcOffset(sourceDate))
Dim utcTime2 As Date = utcTime1.DateTime
If utcTime1.Offset.Equals(TimeZoneInfo.Local.GetUtcOffset(utcTime1.DateTime)) Then
utcTime2 = DateTime.SpecifyKind(utcTime2, DateTimeKind.Local)
End If
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
プロパティを使用して、値をローカルの値に変換することもできます。 返される値のプロパティは次の通りです。 次のコードでは、オフセットがローカル タイム ゾーンの値に対応する値を変換するときに、 プロパティを使用します。
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($"{localTime1} converted to {localTime2} {localTime2.Kind}");
// 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
Dim sourceDate As Date = #06/19/2008 7:00AM#
Dim localTime1 As New DateTimeOffset(sourceDate, _
TimeZoneInfo.Local.GetUtcOffset(sourceDate))
Dim localTime2 As Date = 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
プロパティを使用して値を取得する場合、プロパティの アクセサーは、最初に値を UTC に変換してから、 メソッドを呼び出してローカル時刻に変換します。 この動作は、 プロパティから値を取得して、型変換を実行すると同時にタイム ゾーン変換を実行できることを意味します。 また、変換を実行する際にローカル タイム ゾーンの調整規則が適用されることを意味します。 次のコードは、 プロパティを使用して、型とタイム ゾーン変換の両方を実行する方法を示しています。 サンプル出力は、太平洋タイム ゾーン (米国およびカナダ) に設定されたマシン用です。 11 月の日付は太平洋標準時 (UTC-8)、6 月の日付は夏時間 (UTC-7) です。
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($"{originalDate} converted to {localDate} {localDate.Kind}");
// 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($"{originalDate} converted to {localDate} {localDate.Kind}");
// The example displays the following output to the console,
// when you run it on a machine that is set to Pacific Time (US & Canada):
// 6/18/2008 7:00:00 AM -05:00 converted to 6/18/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
Dim originalDate As DateTimeOffset
Dim localDate As Date
' Convert time originating in a different time zone
originalDate = New DateTimeOffset(#06/19/2008 7:00AM#, _
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(#11/04/2007 4:00AM#, _
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,
' when you run it on a machine that is set to Pacific Time (US & Canada):
' 6/18/2008 7:00:00 AM -05:00 converted to 6/18/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
汎用変換方法
次の例では、値を値に変換する という名前のメソッドを定義します。 オフセットに基づいて、 値が UTC 時刻、現地時刻、またはその他の時刻であるかどうかを判断し、それに応じて、返される日時値の プロパティを定義します。
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;
}
Function ConvertFromDateTimeOffset(dateTime As DateTimeOffset) As Date
If dateTime.Offset.Equals(TimeSpan.Zero) Then
Return dateTime.UtcDateTime
ElseIf dateTime.Offset.Equals(TimeZoneInfo.Local.GetUtcOffset(dateTime.DateTime))
Return Date.SpecifyKind(dateTime.DateTime, DateTimeKind.Local)
Else
Return dateTime.DateTime
End If
End Function
次の例では、 メソッドを呼び出して、UTC 時刻、現地時刻、および米国中部標準時ゾーンの時刻を表す 値を変換します。
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($"{utcTime} converted to {returnedDate} {returnedDate.Kind}");
// Convert local time
DateTimeOffset localTime = new DateTimeOffset(timeComponent,
TimeZoneInfo.Local.GetUtcOffset(timeComponent));
returnedDate = ConvertFromDateTimeOffset(localTime);
Console.WriteLine($"{localTime} converted to {returnedDate} {returnedDate.Kind}");
// Convert Central Standard Time
DateTimeOffset cstTime = new DateTimeOffset(timeComponent,
TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time").GetUtcOffset(timeComponent));
returnedDate = ConvertFromDateTimeOffset(cstTime);
Console.WriteLine($"{cstTime} converted to {returnedDate} {returnedDate.Kind}");
// 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
Dim timeComponent As Date = #06/19/2008 7:00AM#
Dim returnedDate As Date
' Convert UTC time
Dim utcTime As New DateTimeOffset(timeComponent, TimeSpan.Zero)
returnedDate = ConvertFromDateTimeOffset(utcTime)
Console.WriteLine("{0} converted to {1} {2}", _
utcTime, _
returnedDate, _
returnedDate.Kind.ToString())
' Convert local time
Dim localTime As 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
Dim cstTime As 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 つの前提が常に有効であるとは限りません。
オフセットが設定された日付と時刻の値がUTCを表すと仮定しています。 実際、UTC は特定のタイム ゾーンの時刻ではなく、世界のタイム ゾーン内の時刻が標準化されている時間です。 タイム ゾーンには、 のオフセットを設定することもできます。
オフセットがローカル タイム ゾーンのオフセットと等しい日付と時刻がローカル タイム ゾーンを表していることを前提としています。 日付と時刻の値は元のタイム ゾーンとの関連付けが解除されるため、そうではない可能性があります。日付と時刻は、同じオフセットを持つ別のタイム ゾーンで発生している可能性があります。
こちらも参照ください
- 日付、時刻、時間帯
.NET