Freigeben über


Konvertieren von Zeiten zwischen Zeitzonen

Es wird immer wichtiger für jede Anwendung, die mit Datums- und Uhrzeitangaben arbeitet, um Unterschiede zwischen Zeitzonen zu behandeln. Eine Anwendung kann nicht mehr davon ausgehen, dass alle Zeiten in der Ortszeit ausgedrückt werden können, was die von der DateTime Struktur verfügbare Zeit ist. Beispielsweise wird eine Webseite, die die aktuelle Zeit im östlichen Teil der VEREINIGTEN Staaten anzeigt, an Glaubwürdigkeit für einen Kunden in Ostasien mangeln. In diesem Artikel wird erläutert, wie Sie Zeiten aus einer Zeitzone in eine andere konvertieren und DateTimeOffset Werte konvertieren, die eine begrenzte Zeitzoneninformation aufweisen.

Konvertieren in koordinierte Weltzeit

Coordinated Universal Time (UTC) ist ein präzisionsgenauer Atomzeitstandard. Die Zeitzonen der Welt werden als positive oder negative Offsets von UTC ausgedrückt. So stellt UTC eine zeitzonenfreie oder zeitzonenneutrale Zeit bereit. Die Verwendung von UTC wird empfohlen, wenn die Portabilität eines Datums und einer Uhrzeit über Computer hinweg wichtig ist. Ausführliche Informationen und andere bewährte Methoden zur Verwendung von Datums- und Uhrzeitangaben finden Sie unter Codieren bewährter Methoden mit DateTime in .NET Framework. Das Konvertieren einzelner Zeitzonen in UTC erleichtert Zeitvergleiche.

Hinweis

Sie können eine DateTimeOffset Struktur auch serialisieren, um einen einzelnen Punkt eindeutig darzustellen. Da DateTimeOffset Objekte einen Datums- und Uhrzeitwert zusammen mit dem Offset von UTC speichern, stellen sie immer einen bestimmten Punkt in Bezug auf UTC dar.

Die einfachste Möglichkeit zum Konvertieren einer Zeit in UTC ist das Aufrufen der static (Shared in Visual Basic) TimeZoneInfo.ConvertTimeToUtc(DateTime) -Methode. Die genaue Konvertierung, die von der Methode ausgeführt wird, hängt vom Wert der Eigenschaft des dateTime Parameters Kind ab, wie die folgende Tabelle zeigt:

DateTime.Kind Umwandlung
DateTimeKind.Local Wandelt die Ortszeit in UTC um.
DateTimeKind.Unspecified Angenommen, der dateTime Parameter ist ortszeit und konvertiert die Ortszeit in UTC.
DateTimeKind.Utc Gibt den dateTime Parameter unverändert zurück.

Der folgende Code konvertiert die aktuelle Ortszeit in UTC und zeigt das Ergebnis in der Konsole an:

DateTime dateNow = DateTime.Now;
Console.WriteLine($"The date and time are {TimeZoneInfo.ConvertTimeToUtc(dateNow)} UTC.");
Dim dateNow As Date = Date.Now
Console.WriteLine("The date and time are {0} UTC.", _
                  TimeZoneInfo.ConvertTimeToUtc(dateNow))

Wenn der Datums- und Uhrzeitwert nicht die lokale Uhrzeit oder UTC darstellt, gibt die ToUniversalTime Methode wahrscheinlich ein fehlerhaftes Ergebnis zurück. Sie können jedoch die TimeZoneInfo.ConvertTimeToUtc Methode verwenden, um das Datum und die Uhrzeit aus einer angegebenen Zeitzone zu konvertieren. Ausführliche Informationen zum Abrufen eines TimeZoneInfo Objekts, das die Zielzeitzone darstellt, finden Sie unter Suchen der zeitzonen, die in einem lokalen System definiert sind. Der folgende Code verwendet die TimeZoneInfo.ConvertTimeToUtc Methode zum Konvertieren der Eastern Standard Time in UTC:

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 {TimeZoneInfo.ConvertTimeToUtc(easternTime, easternZone)} UTC.");
}
catch (TimeZoneNotFoundException)
{
    Console.WriteLine($"Unable to find the {easternZoneId} zone in the registry.");
}
catch (InvalidTimeZoneException)
{
    Console.WriteLine($"Registry data on the {easternZoneId} zone has been corrupted.");
}
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

Die TimeZoneInfo.ConvertTimeToUtc-Methode löst ein ArgumentException aus, wenn die DateTime-Eigenschaft des Kind-Objekts und die Zeitzone nicht übereinstimmen. Ein Konflikt tritt auf, wenn die Kind Eigenschaft DateTimeKind.Local ist, aber das TimeZoneInfo Objekt nicht die lokale Zeitzone darstellt, oder wenn die Kind Eigenschaft DateTimeKind.Utc ist, aber das TimeZoneInfo Objekt nicht gleich TimeZoneInfo.Utc ist.

Alle diese Methoden verwenden DateTime Werte als Parameter und geben einen DateTime Wert zurück. Für DateTimeOffset Werte weist die DateTimeOffset Struktur eine ToUniversalTime Instanzmethode auf, die das Datum und die Uhrzeit der aktuellen Instanz in UTC konvertiert. Im folgenden Beispiel wird die ToUniversalTime Methode aufgerufen, um eine Ortszeit und mehrere andere Zeiten nach UTC zu konvertieren.

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: {localTime}");
Console.WriteLine();

// Convert local time to offset 0 and assign to otherTime
otherTime = localTime.ToOffset(TimeSpan.Zero);
Console.WriteLine($"Other time: {otherTime}");
Console.WriteLine($"{localTime} = {otherTime}: {localTime.Equals(otherTime)}");
Console.WriteLine($"{localTime} exactly equals {otherTime}: {localTime.EqualsExact(otherTime)}");
Console.WriteLine();

// Convert other time to UTC
universalTime = localTime.ToUniversalTime();
Console.WriteLine($"Universal time: {universalTime}");
Console.WriteLine($"{otherTime} = {universalTime}: {universalTime.Equals(otherTime)}");
Console.WriteLine($"{otherTime} exactly equals {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
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   

Konvertieren von UTC in eine bestimmte Zeitzone

Informationen zum Konvertieren von UTC in Ortszeit finden Sie im folgenden Abschnitt zum Konvertieren von UTC in lokale Zeit . Um UTC in die Zeit einer von Ihnen festgelegten Zeitzone zu konvertieren, rufen Sie die ConvertTimeFromUtc-Methode auf. Die Methode akzeptiert zwei Parameter:

  • Die UTC, die konvertiert werden soll. Dies muss ein DateTime-Wert sein, dessen Kind-Eigenschaft auf Unspecified oder Utc gesetzt ist.

  • Die Zeitzone, in die die UTC konvertiert werden soll.

Der folgende Code konvertiert UTC in die zentrale Standardzeit:

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.");
}
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

Konvertieren von UTC in Ortszeit

Rufen Sie die ToLocalTime Methode des DateTime Objekts auf, dessen Zeit Sie konvertieren möchten, um UTC in ortszeit zu konvertieren. Das genaue Verhalten der Methode hängt vom Wert der Eigenschaft des Objekts Kind ab, wie in der folgenden Tabelle dargestellt:

DateTime.Kind Umwandlung
DateTimeKind.Local Gibt den DateTime Wert unverändert zurück.
DateTimeKind.Unspecified Es wird davon ausgegangen, dass der DateTime Wert UTC ist und die UTC in die Ortszeit konvertiert.
DateTimeKind.Utc Wandelt den DateTime Wert in die Ortszeit um.

Hinweis

Die TimeZone.ToLocalTime Methode verhält sich identisch mit der DateTime.ToLocalTime Methode. Zum Konvertieren wird ein einzelner Parameter verwendet, der den Datums- und Uhrzeitwert darstellt.

Sie können die Uhrzeit auch in einer bestimmten Zeitzone in lokale Zeit konvertieren, indem Sie die static (Shared in Visual Basic)- TimeZoneInfo.ConvertTime Methode verwenden. Diese Technik wird im nächsten Abschnitt erläutert.

Konvertieren zwischen zwei beliebigen Zeitzonen

Sie können zwischen zwei beliebigen Zeitzonen konvertieren, indem Sie eine der folgenden beiden static Methoden (Shared in Visual Basic) der TimeZoneInfo Klasse verwenden:

  • ConvertTime

    Die Parameter dieser Methode sind der zu konvertierende Datums- und Uhrzeitwert, ein TimeZoneInfo Objekt, das die Zeitzone des Datums- und Uhrzeitwerts darstellt, und ein TimeZoneInfo Objekt, das die Zeitzone darstellt, in die der Datums- und Uhrzeitwert konvertiert werden soll.

  • ConvertTimeBySystemTimeZoneId

    Die Parameter dieser Methode sind der zu konvertierende Datums- und Uhrzeitwert, der Bezeichner der Zeitzone des Datums- und Uhrzeitwerts und der Bezeichner der Zeitzone, in die der Datums- und Uhrzeitwert konvertiert werden soll.

Beide Methoden erfordern, dass die Kind-Eigenschaft des zu konvertierenden Datums- und Uhrzeitwerts und das TimeZoneInfo-Objekt oder der Zeitzonenbezeichner, der die Zeitzone darstellt, korrespondieren. Andernfalls wird eine ArgumentException ausgelöst. Wenn beispielsweise die Kind Eigenschaft des Datums- und Uhrzeitwerts lautet DateTimeKind.Local, wird eine Ausnahme ausgelöst, wenn das Objekt, das TimeZoneInfo als Parameter an die Methode übergeben wird, nicht gleich TimeZoneInfo.Localist. Eine Ausnahme wird auch ausgelöst, wenn der als Parameter an die Methode übergebene Bezeichner nicht gleich TimeZoneInfo.Local.Idist.

Im folgenden Beispiel wird die ConvertTime Methode verwendet, um von hawaiianischer Standardzeit in ortszeit zu konvertieren:

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.");
}
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

Konvertieren von DateTimeOffset-Werten

Datums- und Uhrzeitwerte, die durch DateTimeOffset Objekte dargestellt werden, sind nicht vollständig zeitzonenfähig, da das Objekt zu dem Zeitpunkt, zu dem es instanziiert wird, von der Zeitzone getrennt ist. In vielen Fällen muss eine Anwendung jedoch einfach ein Datum und eine Uhrzeit basierend auf zwei unterschiedlichen Offsets von UTC und nicht auf Zeit in bestimmten Zeitzonen konvertieren. Zum Ausführen dieser Konvertierung können Sie die Methode der aktuellen Instanz ToOffset aufrufen. Der einzelne Parameter der Methode ist der Offset des neuen Datums- und Uhrzeitwerts, den die Methode zurückgibt.

Wenn beispielsweise das Datum und die Uhrzeit einer Benutzeranforderung für eine Webseite bekannt ist und als Zeichenfolge im Format MM/dd/yyyyy hh:mm:ss zzzzzz serialisiert wird, konvertiert die folgende ReturnTimeOnServer Methode diesen Datums- und Uhrzeitwert in das Datum und die Uhrzeit auf dem Webserver:

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;
   }
}
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

Wenn die Methode die Zeichenfolge "9/1/2007 5:32:07 -05:00" übergibt, die das Datum und die Uhrzeit in einer Zeitzone von fünf Stunden vor UTC darstellt, gibt sie "9/1/2007 3:32:07: 07:00" für einen Server zurück, der sich in der US-Pazifischen Standardzeitzone befindet.

Die TimeZoneInfo Klasse enthält auch eine Überladung der TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo) Methode, die Zeitzonenkonvertierungen mit ToOffset(TimeSpan) Werten ausführt. 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. Beispielsweise könnte die ReturnTimeOnServer Methode im vorherigen Beispiel wie folgt umgeschrieben werden, um die ConvertTime(DateTimeOffset, TimeZoneInfo) Methode aufzurufen.

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;
   }
}
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

Siehe auch