Konvertieren von Uhrzeiten zwischen Zeitzonen
Für Anwendungen, die mit Datumsangaben und Uhrzeiten arbeiten, wird es immer wichtiger, Unterschiede zwischen Zeitzonen verarbeiten zu können. Eine Anwendung kann nicht länger davon ausgehen, dass alle Uhrzeiten in Ortszeit ausgedrückt werden können, also in der Uhrzeit, die durch die DateTime-Struktur festgelegt ist. So ist beispielsweise eine Webseite, auf der die aktuelle Uhrzeit im Osten der USA angezeigt wird, für einen Benutzer in Ostasien nicht sehr glaubwürdig. In diesem Thema wird erläutert, wie Uhrzeiten von einer Zeitzone in eine andere konvertiert werden können und wie DateTimeOffset-Werte mit eingeschränkter Zeitzonenunterstützung konvertiert werden.
Konvertieren in koordinierte Weltzeit (Coordinated Universal Time, UTC)
Bei der koordinierten Weltzeit (Coordinated Universal Time, UTC) handelt es sich um einen höchst präzisen Atomzeitstandard. Die Zeitzonen der Welt werden als positive oder negative Offsets von UTC ausgedrückt. UTC stellt daher eine Art Zeit dar, die unabhängig von Zeitzonen bzw. neutral ist. Die Verwendung der UTC-Zeit wird empfohlen, wenn die Portabilität von Datum und Uhrzeit zwischen Computern wichtig ist. (Ausführliche Informationen und andere empfohlene Vorgehensweisen finden Sie unter Coding Best Practices Using DateTime in the .NET Framework.) Durch das Konvertieren einzelner Zeitzonen in UTC wird der Vergleich von Uhrzeiten vereinfacht.
Hinweis |
---|
Sie können eine DateTimeOffset-Struktur auch serialisieren, um einen bestimmten Zeitpunkt eindeutig darzustellen.Da DateTimeOffset-Objekte einen Datums- und Uhrzeitwert zusammen mit dem Offset von UTC speichern, geben sie stets einen bestimmten Zeitpunkt in Bezug auf UTC an. |
Eine Uhrzeit lässt sich am einfachsten in UTC konvertieren, indem die static (Shared in Visual Basic) TimeZoneInfo.ConvertTimeToUtc(DateTime)-Methode aufgerufen wird. Die tatsächlich durch die Methode ausgeführte Konvertierung ist vom Wert der Kind-Eigenschaft des dateTime-Parameters abhängig, wie in der folgenden Tabelle dargestellt.
DateTime.Kind-Eigenschaft |
Conversion |
---|---|
Konvertiert Ortszeit in UTC. |
|
Nimmt an, dass der dateTime-Parameter Ortszeit darstellt, und konvertiert Ortszeit in UTC. |
|
Gibt den dateTime-Parameter unverändert zurück. |
Im folgenden Code wird die aktuelle Ortszeit in UTC konvertiert, und das Ergebnis wird auf der Konsole angezeigt.
Dim dateNow As Date = Date.Now
Console.WriteLine("The date and time are {0} UTC.", _
TimeZoneInfo.ConvertTimeToUtc(dateNow))
DateTime dateNow = DateTime.Now;
Console.WriteLine("The date and time are {0} UTC.",
TimeZoneInfo.ConvertTimeToUtc(dateNow));
Hinweis |
---|
Die TimeZoneInfo.ConvertTimeToUtc(DateTime)-Methode erzeugt notwendigerweise keine Ergebnisse, die mit der TimeZone.ToUniversalTime-Methode und DateTime.ToUniversalTime-Methode identisch sind.Wenn für die lokale Zeitzone des Hostsystems mehrere Anpassungsregeln gelten, wendet TimeZoneInfo.ConvertTimeToUtc(DateTime) die entsprechende Regel auf ein bestimmtes Datum und eine bestimmte Uhrzeit an.Die anderen beiden Methoden wenden immer die letzte Anpassungsregel an. |
Wenn der Datums- und Uhrzeitwert weder die Ortszeit noch UTC darstellt, gibt die ToUniversalTime-Methode wahrscheinlich ein falsches Ergebnis zurück. Mit der TimeZoneInfo.ConvertTimeToUtc-Methode können Sie jedoch das Datum und die Uhrzeit aus einer bestimmten Zeitzone konvertieren. (Ausführliche Informationen zum Abrufen eines TimeZoneInfo-Objekts, das die Zielzeitzone darstellt, finden Sie unter Suchen der auf einem lokalen System definierten Zeitzonen.) Im folgenden Code wird die TimeZoneInfo.ConvertTimeToUtc-Methode verwendet, um Eastern Normalzeit in UTC zu konvertieren.
Dim easternTime As New Date(2007, 01, 02, 12, 16, 00)
Dim easternZoneId As String = "Eastern Standard Time"
Try
Dim easternZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(easternZoneId)
Console.WriteLine("The date and time are {0} UTC.", _
TimeZoneInfo.ConvertTimeToUtc(easternTime, easternZone))
Catch e As TimeZoneNotFoundException
Console.WriteLine("Unable to find the {0} zone in the registry.", _
easternZoneId)
Catch e As InvalidTimeZoneException
Console.WriteLine("Registry data on the {0} zone has been corrupted.", _
easternZoneId)
End Try
DateTime easternTime = new DateTime(2007, 01, 02, 12, 16, 00);
string easternZoneId = "Eastern Standard Time";
try
{
TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById(easternZoneId);
Console.WriteLine("The date and time are {0} UTC.",
TimeZoneInfo.ConvertTimeToUtc(easternTime, easternZone));
}
catch (TimeZoneNotFoundException)
{
Console.WriteLine("Unable to find the {0} zone in the registry.",
easternZoneId);
}
catch (InvalidTimeZoneException)
{
Console.WriteLine("Registry data on the {0} zone has been corrupted.",
easternZoneId);
}
Beachten Sie, dass die Methode eine ArgumentException auslöst, wenn die Kind-Eigenschaft des DateTime-Objekts und die Zeitzone nicht übereinstimmen. Eine fehlende Übereinstimmung tritt dann auf, wenn die Kind-Eigenschaft DateTimeKind.Local ist, das TimeZoneInfo-Objekt jedoch nicht die lokale Zeitzone darstellt, oder wenn die Kind-Eigenschaft DateTimeKind.Utc ist, das TimeZoneInfo-Objekt jedoch nicht DateTimeKind.Utc entspricht.
Alle diese Methoden verwenden DateTime-Werte als Parameter und geben einen DateTime-Wert zurück. Für DateTimeOffset-Werte verfügt die DateTimeOffset-Struktur über eine ToUniversalTime-Instanzmethode, mit der Datum und Uhrzeit der aktuellen Instanz in UTC konvertiert werden. Im folgenden Beispiel werden mithilfe der ToUniversalTime-Methode die Ortszeit und mehrere andere Uhrzeiten in koordinierte Weltzeit (UTC) konvertiert.
Dim localTime, otherTime, universalTime As DateTimeOffset
' Define local time in local time zone
localTime = New DateTimeOffset(#6/15/2007 12:00:00PM#)
Console.WriteLine("Local time: {0}", localTime)
Console.WriteLine()
' Convert local time to offset 0 and assign to otherTime
otherTime = localTime.ToOffset(TimeSpan.Zero)
Console.WriteLine("Other time: {0}", otherTime)
Console.WriteLine("{0} = {1}: {2}", _
localTime, otherTime, _
localTime.Equals(otherTime))
Console.WriteLine("{0} exactly equals {1}: {2}", _
localTime, otherTime, _
localTime.EqualsExact(otherTime))
Console.WriteLine()
' Convert other time to UTC
universalTime = localTime.ToUniversalTime()
Console.WriteLine("Universal time: {0}", universalTime)
Console.WriteLine("{0} = {1}: {2}", _
otherTime, universalTime, _
universalTime.Equals(otherTime))
Console.WriteLine("{0} exactly equals {1}: {2}", _
otherTime, universalTime, _
universalTime.EqualsExact(otherTime))
Console.WriteLine()
' The example produces the following output to the console:
' Local time: 6/15/2007 12:00:00 PM -07:00
'
' Other time: 6/15/2007 7:00:00 PM +00:00
' 6/15/2007 12:00:00 PM -07:00 = 6/15/2007 7:00:00 PM +00:00: True
' 6/15/2007 12:00:00 PM -07:00 exactly equals 6/15/2007 7:00:00 PM +00:00: False
'
' Universal time: 6/15/2007 7:00:00 PM +00:00
' 6/15/2007 7:00:00 PM +00:00 = 6/15/2007 7:00:00 PM +00:00: True
' 6/15/2007 7:00:00 PM +00:00 exactly equals 6/15/2007 7:00:00 PM +00:00: True
DateTimeOffset localTime, otherTime, universalTime;
// Define local time in local time zone
localTime = new DateTimeOffset(new DateTime(2007, 6, 15, 12, 0, 0));
Console.WriteLine("Local time: {0}", localTime);
Console.WriteLine();
// Convert local time to offset 0 and assign to otherTime
otherTime = localTime.ToOffset(TimeSpan.Zero);
Console.WriteLine("Other time: {0}", otherTime);
Console.WriteLine("{0} = {1}: {2}",
localTime, otherTime,
localTime.Equals(otherTime));
Console.WriteLine("{0} exactly equals {1}: {2}",
localTime, otherTime,
localTime.EqualsExact(otherTime));
Console.WriteLine();
// Convert other time to UTC
universalTime = localTime.ToUniversalTime();
Console.WriteLine("Universal time: {0}", universalTime);
Console.WriteLine("{0} = {1}: {2}",
otherTime, universalTime,
universalTime.Equals(otherTime));
Console.WriteLine("{0} exactly equals {1}: {2}",
otherTime, universalTime,
universalTime.EqualsExact(otherTime));
Console.WriteLine();
// The example produces the following output to the console:
// Local time: 6/15/2007 12:00:00 PM -07:00
//
// Other time: 6/15/2007 7:00:00 PM +00:00
// 6/15/2007 12:00:00 PM -07:00 = 6/15/2007 7:00:00 PM +00:00: True
// 6/15/2007 12:00:00 PM -07:00 exactly equals 6/15/2007 7:00:00 PM +00:00: False
//
// Universal time: 6/15/2007 7:00:00 PM +00:00
// 6/15/2007 7:00:00 PM +00:00 = 6/15/2007 7:00:00 PM +00:00: True
// 6/15/2007 7:00:00 PM +00:00 exactly equals 6/15/2007 7:00:00 PM +00:00: True
Konvertieren von UTC in eine festgelegte Zeitzone
Weitere Informationen zum Konvertieren von UTC in Ortszeit finden Sie im folgenden Abschnitt, "Konvertieren von UTC in Ortszeit". Um UTC in eine Uhrzeit einer beliebigen festgelegten Zeitzone zu konvertieren, rufen Sie die ConvertTimeFromUtc-Methode auf. Diese Methode verwendet zwei Parameter:
Die zu konvertierende UTC. Hierbei muss es sich um einen DateTime-Wert handeln, dessen Kind-Eigenschaft auf DateTimeKind.Utc oder DateTimeKind.Unspecified festgelegt ist.
Die Zeitzone, in die UTC konvertiert werden soll.
Im folgenden Code wird UTC in Central Normalzeit konvertiert.
Dim timeUtc As Date = Date.UtcNow
Try
Dim cstZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")
Dim cstTime As Date = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, cstZone)
Console.WriteLine("The date and time are {0} {1}.", _
cstTime, _
IIf(cstZone.IsDaylightSavingTime(cstTime), _
cstZone.DaylightName, cstZone.StandardName))
Catch e As TimeZoneNotFoundException
Console.WriteLine("The registry does not define the Central Standard Time zone.")
Catch e As InvalidTimeZoneException
Console.WriteLine("Registry data on the Central Standard Time zone has been corrupted.")
End Try
DateTime timeUtc = DateTime.UtcNow;
try
{
TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
DateTime cstTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, cstZone);
Console.WriteLine("The date and time are {0} {1}.",
cstTime,
cstZone.IsDaylightSavingTime(cstTime) ?
cstZone.DaylightName : cstZone.StandardName);
}
catch (TimeZoneNotFoundException)
{
Console.WriteLine("The registry does not define the Central Standard Time zone.");
}
catch (InvalidTimeZoneException)
{
Console.WriteLine("Registry data on the Central STandard Time zone has been corrupted.");
}
Konvertieren von UTC in Ortszeit
Rufen Sie zum Konvertieren von UTC in Ortszeit die ToLocalTime-Methode des DateTime-Objekts auf, dessen Uhrzeit Sie konvertieren möchten. Das genaue Verhalten der Methode ist vom Wert der Kind-Eigenschaft des Objekts abhängig, wie in der folgenden Tabelle dargestellt.
DateTime.Kind-Eigenschaft |
Conversion |
---|---|
DateTimeKind.Local |
Gibt den DateTime-Wert unverändert zurück. |
DateTimeKind.Unspecified |
Nimmt an, dass der DateTime-Wert UTC ist, und konvertiert UTC in Ortszeit. |
DateTimeKind.Utc |
Konvertiert den DateTime-Wert in Ortszeit. |
Hinweis Das Verhalten der TimeZone.ToLocalTime-Methode ist mit dem der DateTime.ToLocalTime-Methode identisch. Sie verwendet einen einzelnen Parameter, wobei es sich um den zu konvertierenden Datums- und Uhrzeitwert handelt.
Sie können die Uhrzeit auch in die Ortszeit einer beliebigen festgelegten Zeitzone konvertieren, indem Sie die static (Shared in Visual Basic) TimeZoneInfo.ConvertTime-Methode verwenden. Diese Vorgehensweise wird im nächsten Abschnitt erläutert.
Konvertieren zwischen zwei beliebigen Zeitzonen
Sie können Uhrzeiten zwischen zwei beliebigen Zeitzonen konvertieren, indem Sie eine der beiden folgenden static-Methoden (Shared in Visual Basic) der TimeZoneInfo-Klasse verwenden:
-
Die Parameter dieser Methode sind das Datum und die Uhrzeit, die konvertiert werden sollen, ein TimeZoneInfo-Objekt, das die Zeitzone des Datums- und Uhrzeitwerts darstellt, sowie ein TimeZoneInfo-Objekt, das die Zeitzone darstellt, in die der Datums- und Uhrzeitwert konvertiert werden soll.
-
Die Parameter dieser Methode sind das Datum und die Uhrzeit, die konvertiert werden sollen, ein Zeitzonenbezeichner des Datums- und Uhrzeitwerts sowie ein Bezeichner der Zeitzone, in die der Datums- und Uhrzeitwert konvertiert werden soll.
Für beide Methoden ist erforderlich, dass die Kind-Eigenschaft des zu konvertierenden Datums- und Uhrzeitwerts und das TimeZoneInfo-Objekt oder der Zeitzonenbezeichner, der seine Zeitzone darstellt, einander entsprechen. Andernfalls wird eine ArgumentException ausgelöst. Wenn zum Beispiel die Kind-Eigenschaft des Datums- und Uhrzeitwerts DateTimeKind.Local lautet, wird eine Ausnahme ausgelöst, wenn das als Parameter an die Methode übergebene TimeZoneInfo-Objekt nicht gleich TimeZoneInfo.Local ist. Es wird auch dann eine Ausnahme ausgelöst, wenn der als Parameter an die Methode übergebene Bezeichner nicht gleich TimeZoneInfo.Local.Id ist.
Im folgenden Beispiel wird die ConvertTime-Methode zum Konvertieren von Hawaii Normalzeit in Ortszeit verwendet.
Dim hwTime As Date = #2/01/2007 8:00:00 AM#
Try
Dim hwZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time")
Console.WriteLine("{0} {1} is {2} local time.", _
hwTime, _
IIf(hwZone.IsDaylightSavingTime(hwTime), hwZone.DaylightName, hwZone.StandardName), _
TimeZoneInfo.ConvertTime(hwTime, hwZone, TimeZoneInfo.Local))
Catch e As TimeZoneNotFoundException
Console.WriteLine("The registry does not define the Hawaiian Standard Time zone.")
Catch e As InvalidTimeZoneException
Console.WriteLine("Registry data on the Hawaiian Standard Time zone has been corrupted.")
End Try
DateTime hwTime = new DateTime(2007, 02, 01, 08, 00, 00);
try
{
TimeZoneInfo hwZone = TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time");
Console.WriteLine("{0} {1} is {2} local time.",
hwTime,
hwZone.IsDaylightSavingTime(hwTime) ? hwZone.DaylightName : hwZone.StandardName,
TimeZoneInfo.ConvertTime(hwTime, hwZone, TimeZoneInfo.Local));
}
catch (TimeZoneNotFoundException)
{
Console.WriteLine("The registry does not define the Hawaiian Standard Time zone.");
}
catch (InvalidTimeZoneException)
{
Console.WriteLine("Registry data on the Hawaiian STandard Time zone has been corrupted.");
}
Konvertieren von DateTimeOffset-Werten
Datums- und Uhrzeitwerte, die durch DateTimeOffset-Objekte dargestellt werden, unterstützen Zeitzonen nicht vollständig, da das Objekt zum Zeitpunkt der Instanziierung nicht mit der Zeitzone verknüpft wird. In vielen Fällen muss die Anwendung einfach nur ein Datum und eine Uhrzeit basierend auf zwei verschiedenen Offsets von UTC konvertieren, statt basierend auf der Uhrzeit in bestimmten Zeitzonen. Um diese Konvertierung auszuführen, können Sie die ToOffset-Methode der aktuellen Instanz aufrufen. Der einzige Parameter dieser Methode ist der Offset des neuen Datums- und Uhrzeitwerts, den die Methode zurückgeben soll.
Wenn zum Beispiel das Datum und die Uhrzeit einer Benutzeranforderung für eine Webseite bekannt und als Zeichenfolge im Format MM/tt/jjjj hh:mm:ss zzzz serialisiert sind, konvertiert die folgende ReturnTimeOnServer-Methode diesen Datums- und Uhrzeitwert in Datum und Uhrzeit auf dem Webserver.
Public Function ReturnTimeOnServer(clientString As String) As DateTimeOffset
Dim format As String = "M/d/yyyy H:m:s zzz"
Dim serverOffset As TimeSpan = TimeZoneInfo.Local.GetUtcOffset(DateTimeOffset.Now)
Try
Dim clientTime As DateTimeOffset = DateTimeOffset.ParseExact(clientString, format, CultureInfo.InvariantCulture)
Dim serverTime As DateTimeOffset = clientTime.ToOffset(serverOffset)
Return serverTime
Catch e As FormatException
Return DateTimeOffset.MinValue
End Try
End Function
public DateTimeOffset ReturnTimeOnServer(string clientString)
{
string format = @"M/d/yyyy H:m:s zzz";
TimeSpan serverOffset = TimeZoneInfo.Local.GetUtcOffset(DateTimeOffset.Now);
try
{
DateTimeOffset clientTime = DateTimeOffset.ParseExact(clientString, format, CultureInfo.InvariantCulture);
DateTimeOffset serverTime = clientTime.ToOffset(serverOffset);
return serverTime;
}
catch (FormatException)
{
return DateTimeOffset.MinValue;
}
}
Wenn die Zeichenfolge "9/1/2007 5:32:07 -05:00", die ein Datum und eine Uhrzeit in einer Zeitzone fünf Stunden vor UTC darstellt, an die Methode übergeben wird, gibt die Methode "9/1/2007 3:32:07 AM -07:00" für einen Server zurück, der in der Zeitzone Pacific Normalzeit liegt.
Die TimeZoneInfo-Klasse umfasst auch eine Überladung der TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo)-Methode, mit der Zeitzonenkonvertierungen anhand von DateTimeOffset-Werten durchgeführt werden. Die Parameter der Methode sind ein DateTimeOffset-Wert und ein Verweis auf die Zeitzone, in die die Uhrzeit konvertiert werden soll. Der Methodenaufruf gibt einen DateTimeOffset-Wert zurück. Die ReturnTimeOnServer-Methode im vorhergehenden Beispiel kann beispielsweise so umgeschrieben werden, dass die ConvertTime(DateTimeOffset, TimeZoneInfo)-Methode aufgerufen wird.
Public Function ReturnTimeOnServer(clientString As String) As DateTimeOffset
Dim format As String = "M/d/yyyy H:m:s zzz"
Try
Dim clientTime As DateTimeOffset = DateTimeOffset.ParseExact(clientString, format, CultureInfo.InvariantCulture)
Dim serverTime As DateTimeOffset = TimeZoneInfo.ConvertTime(clientTime, TimeZoneInfo.Local)
Return serverTime
Catch e As FormatException
Return DateTimeOffset.MinValue
End Try
End Function
public DateTimeOffset ReturnTimeOnServer(string clientString)
{
string format = @"M/d/yyyy H:m:s zzz";
try
{
DateTimeOffset clientTime = DateTimeOffset.ParseExact(clientString, format,
CultureInfo.InvariantCulture);
DateTimeOffset serverTime = TimeZoneInfo.ConvertTime(clientTime,
TimeZoneInfo.Local);
return serverTime;
}
catch (FormatException)
{
return DateTimeOffset.MinValue;
}
}
Siehe auch
Referenz
Konzepte
Suchen der auf einem lokalen System definierten Zeitzonen