Gewusst wie: Verwenden von Zeitzonen in arithmetischen Datums-und Uhrzeit OperationenHow to: Use time zones in date and time arithmetic

Wenn Sie Datums-und Uhrzeit Arithmetik mit DateTime-oder DateTimeOffset-Werten ausführen, spiegelt das Ergebnis normalerweise keine Zeit Zonen Anpassungsregeln wider.Ordinarily, when you perform date and time arithmetic using DateTime or DateTimeOffset values, the result does not reflect any time zone adjustment rules. Dies gilt auch, wenn die Zeitzone des Datums-und Uhrzeitwerts eindeutig erkennbar ist (z. b. wenn die Kind-Eigenschaft auf Localfestgelegt ist).This is true even when the time zone of the date and time value is clearly identifiable (for example, when the Kind property is set to Local). In diesem Thema wird gezeigt, wie arithmetische Operationen für Datums-und Uhrzeitwerte durchgeführt werden, die zu einer bestimmten Zeitzone gehören.This topic shows how to perform arithmetic operations on date and time values that belong to a particular time zone. Die Ergebnisse der arithmetischen Operationen berücksichtigen die Anpassungsregeln der Zeitzone.The results of the arithmetic operations will reflect the time zone's adjustment rules.

So wenden Sie Anpassungsregeln auf arithmetische Datums- und Uhrzeitoperationen anTo apply adjustment rules to date and time arithmetic

  1. Implementieren Sie eine beliebige Methode, mit der ein Datums- und Uhrzeitwert eng mit der Zeitzone verknüpft wird, zu der er gehört.Implement some method of closely coupling a date and time value with the time zone to which it belongs. Deklarieren Sie z.B. eine Struktur, die sowohl den Datums- als auch den Uhrzeitwert und die Zeitzone einschließt.For example, declare a structure that includes both the date and time value and its time zone. Im folgenden Beispiel wird dieser Ansatz verwendet, um einen DateTime-Wert mit seiner Zeitzone zu verknüpfen.The following example uses this approach to link a DateTime value with its time zone.

    // Define a structure for DateTime values for internal use only
    internal struct TimeWithTimeZone
    {
       TimeZoneInfo TimeZone;
       DateTime Time;
    }
    
    ' Define a structure for DateTime values for internal use only
    Friend Structure TimeWithTimeZone
       Dim TimeZone As TimeZoneInfo
       Dim Time As Date
    End Structure
    
  2. Konvertieren Sie eine Uhrzeit in eine koordinierte Weltzeit (UTC), indem Sie entweder die ConvertTimeToUtc-Methode oder die ConvertTime-Methode aufrufen.Convert a time to Coordinated Universal Time (UTC) by calling either the ConvertTimeToUtc method or the ConvertTime method.

  3. Führen Sie die arithmetische Operation für die UTC-Zeit aus.Perform the arithmetic operation on the UTC time.

  4. Konvertieren Sie die Zeit von UTC in die zugehörige Zeitzone der ursprünglichen Zeit, indem Sie die TimeZoneInfo.ConvertTime(DateTime, TimeZoneInfo)-Methode aufrufen.Convert the time from UTC to the original time's associated time zone by calling the TimeZoneInfo.ConvertTime(DateTime, TimeZoneInfo) method.

BeispielExample

Im folgenden Beispiel werden zwei Stunden und 30 Minuten zum 9. März 2008 um 1:30 UhrThe following example adds two hours and thirty minutes to March 9, 2008, at 1:30 A.M. Central Standard Time hinzugefügt.Central Standard Time. Die Umstellung auf Sommerzeit erfolgt in der Zeitzone dreißig Minuten später, um 2:00 UhrThe time zone's transition to daylight saving time occurs thirty minutes later, at 2:00 A.M. am 9. März 2008 hinzugefügt wurden.on March 9, 2008. Da das Beispiel den vier Schritten folgt, die im vorherigen Abschnitt aufgeführt sind, ist das Ergebnis die richtige Zeit von 5:00 UhrBecause the example follows the four steps listed in the previous section, it correctly reports the resulting time as 5:00 A.M. am 9. März 2008 hinzugefügt wurden.on March 9, 2008.

using System;

public struct TimeZoneTime
{
   public TimeZoneInfo TimeZone;
   public DateTime Time;
   
   public TimeZoneTime(TimeZoneInfo tz, DateTime time)
   {
      if (tz == null) 
         throw new ArgumentNullException("The time zone cannot be a null reference.");
         
      this.TimeZone = tz;
      this.Time = time;   
   }

   public TimeZoneTime AddTime(TimeSpan interval)
   {
      // Convert time to UTC
      DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(this.Time, this.TimeZone);
      // Add time interval to time
      utcTime = utcTime.Add(interval);
      // Convert time back to time in time zone
      return new TimeZoneTime(this.TimeZone, TimeZoneInfo.ConvertTime(utcTime, 
                              TimeZoneInfo.Utc, this.TimeZone));
   }
}

public class TimeArithmetic
{
   public const string tzName = "Central Standard Time";
   
   public static void Main()
   {
      try
      {
         TimeZoneTime cstTime1, cstTime2;
         
         TimeZoneInfo cst = TimeZoneInfo.FindSystemTimeZoneById(tzName);
         DateTime time1 = new DateTime(2008, 3, 9, 1, 30, 0);          
         TimeSpan twoAndAHalfHours = new TimeSpan(2, 30, 0);

         cstTime1 = new TimeZoneTime(cst, time1);
         cstTime2 = cstTime1.AddTime(twoAndAHalfHours);
         Console.WriteLine("{0} + {1} hours = {2}", cstTime1.Time, 
                                                    twoAndAHalfHours.ToString(),  
                                                    cstTime2.Time);
      }
      catch
      {
         Console.WriteLine("Unable to find {0}.", tzName);
      }
   }
}
Public Structure TimeZoneTime
   Public TimeZone As TimeZoneInfo
   Public Time As Date
  
   Public Sub New(tz As TimeZoneInfo, time As Date)
      If tz Is Nothing Then _
         Throw New ArgumentNullException("The time zone cannot be a null reference.")
       
      Me.TimeZone = tz
      Me.Time = time
   End Sub
   
   Public Function AddTime(interval As TimeSpan) As TimeZoneTime
      ' Convert time to UTC
      Dim utcTime As DateTime = TimeZoneInfo.ConvertTimeToUtc(Me.Time, _
                                                              Me.TimeZone)      
      ' Add time interval to time
      utcTime = utcTime.Add(interval)
      ' Convert time back to time in time zone
      Return New TimeZoneTime(Me.TimeZone, TimeZoneInfo.ConvertTime(utcTime, _
                              TimeZoneInfo.Utc, Me.TimeZone))
   End Function
End Structure

Module TimeArithmetic
   Public Const tzName As String = "Central Standard Time"
   
   Public Sub Main()
      Try
         Dim cstTime1, cstTime2 As TimeZoneTime
         
         Dim cst As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(tzName)
         Dim time1 As Date = #03/09/2008 1:30AM#
         Dim twoAndAHalfHours As New TimeSpan(2, 30, 0)
   
         cstTime1 = New TimeZoneTime(cst, time1)
         cstTime2 = cstTime1.AddTime(twoAndAHalfHours)

         Console.WriteLine("{0} + {1} hours = {2}", cstTime1.Time, _
                                                    twoAndAHalfHours.ToString(), _ 
                                                    cstTime2.Time)  
      Catch
         Console.WriteLine("Unable to find {0}.", tzName)
      End Try   
   End Sub   
End Module

Sowohl DateTime als auch DateTimeOffset Werte werden von jeder Zeitzone, zu der Sie gehören, getrennt.Both DateTime and DateTimeOffset values are disassociated from any time zone to which they might belong. Um arithmetische Datums- und Uhrzeitoperationen so durchführen zu können, dass Anpassungsregeln für Zeitzonen automatisch angewendet werden, muss die Zeitzone, zu der der Datums- und Uhrzeitwert gehört, direkt identifizierbar sein.To perform date and time arithmetic in a way that automatically applies a time zone's adjustment rules, the time zone to which any date and time value belongs must be immediately identifiable. Dies bedeutet, dass Datum und Uhrzeit sowie die zugeordnete Zeitzone eng verknüpft sein müssen.This means that a date and time and its associated time zone must be tightly coupled. Hierzu gibt es mehrere Möglichkeiten, darunter die folgenden:There are several ways to do this, which include the following:

  • Nehmen Sie an, dass alle in einer Anwendung verwendeten Uhrzeiten zu einer bestimmten Zeitzone gehören.Assume that all times used in an application belong to a particular time zone. Obwohl dieser Ansatz in einigen Fällen geeignet ist, bietet er jedoch nur eingeschränkte Flexibilität sowie möglicherweise eine eingeschränkte Portabilität.Although appropriate in some cases, this approach offers limited flexibility and possibly limited portability.

  • Definieren Sie einen Typ, der ein Datum und eine Uhrzeit eng mit der zugehörigen Zeitzone verknüpft, indem Sie beide als Felder des Typs einschließen.Define a type that tightly couples a date and time with its associated time zone by including both as fields of the type. Dieser Ansatz wird im Codebeispiel verwendet, in dem eine Struktur zum Speichern des Datums und der Uhrzeit sowie der Zeitzone in zwei Memberfeldern definiert wird.This approach is used in the code example, which defines a structure to store the date and time and the time zone in two member fields.

Das Beispiel veranschaulicht, wie arithmetische Operationen für DateTime Werte ausgeführt werden, sodass Zeit Zonen Anpassungsregeln auf das Ergebnis angewendet werden.The example illustrates how to perform arithmetic operations on DateTime values so that time zone adjustment rules are applied to the result. Allerdings können DateTimeOffset Werte genauso einfach verwendet werden.However, DateTimeOffset values can be used just as easily. Im folgenden Beispiel wird veranschaulicht, wie der Code im ursprünglichen Beispiel so angepasst werden kann, dass anstelle DateTime Werte DateTimeOffset verwendet werden.The following example illustrates how the code in the original example might be adapted to use DateTimeOffset instead of DateTime values.

using System;

public struct TimeZoneTime
{
   public TimeZoneInfo TimeZone;
   public DateTimeOffset Time;
   
   public TimeZoneTime(TimeZoneInfo tz, DateTimeOffset time)
   {
      if (tz == null) 
         throw new ArgumentNullException("The time zone cannot be a null reference.");
         
      this.TimeZone = tz;
      this.Time = time;   
   }

   public TimeZoneTime AddTime(TimeSpan interval)
   {
      // Convert time to UTC
      DateTimeOffset utcTime = TimeZoneInfo.ConvertTime(this.Time, TimeZoneInfo.Utc);      
      // Add time interval to time
      utcTime = utcTime.Add(interval);
      // Convert time back to time in time zone
      return new TimeZoneTime(this.TimeZone, TimeZoneInfo.ConvertTime(utcTime, this.TimeZone));
   }
}

public class TimeArithmetic
{
   public const string tzName = "Central Standard Time";
   
   public static void Main()
   {
      try
      {
         TimeZoneTime cstTime1, cstTime2;
         
         TimeZoneInfo cst = TimeZoneInfo.FindSystemTimeZoneById(tzName);
         DateTime time1 = new DateTime(2008, 3, 9, 1, 30, 0);          
         TimeSpan twoAndAHalfHours = new TimeSpan(2, 30, 0);
         
         cstTime1 = new TimeZoneTime(cst, 
                        new DateTimeOffset(time1, cst.GetUtcOffset(time1)));
         cstTime2 = cstTime1.AddTime(twoAndAHalfHours);
         Console.WriteLine("{0} + {1} hours = {2}", cstTime1.Time, 
                                                    twoAndAHalfHours.ToString(),  
                                                    cstTime2.Time);
      }
      catch
      {
         Console.WriteLine("Unable to find {0}.", tzName);
      }
   }
}
Public Structure TimeZoneTime
   Public TimeZone As TimeZoneInfo
   Public Time As DateTimeOffset
  
   Public Sub New(tz As TimeZoneInfo, time As DateTimeOffset)
      If tz Is Nothing Then _
         Throw New ArgumentNullException("The time zone cannot be a null reference.")
       
      Me.TimeZone = tz
      Me.Time = time
   End Sub
   
   Public Function AddTime(interval As TimeSpan) As TimeZoneTime
      ' Convert time to UTC
      Dim utcTime As DateTimeOffset = TimeZoneInfo.ConvertTime(Me.Time, TimeZoneInfo.Utc)      
      ' Add time interval to time
      utcTime = utcTime.Add(interval)
      ' Convert time back to time in time zone
      Return New TimeZoneTime(Me.TimeZone, TimeZoneInfo.ConvertTime(utcTime, Me.TimeZone))
   End Function
End Structure

Module TimeArithmetic
   Public Const tzName As String = "Central Standard Time"
   
   Public Sub Main()
      Try
         Dim cstTime1, cstTime2 As TimeZoneTime
         
         Dim cst As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(tzName)
         Dim time1 As Date = #03/09/2008 1:30AM#
         Dim twoAndAHalfHours As New TimeSpan(2, 30, 0)
   
         cstTime1 = New TimeZoneTime(cst, _
                        New DateTimeOffset(time1, cst.GetUtcOffset(time1)))
         cstTime2 = cstTime1.AddTime(twoAndAHalfHours)

         Console.WriteLine("{0} + {1} hours = {2}", cstTime1.Time, _
                                                    twoAndAHalfHours.ToString(), _ 
                                                    cstTime2.Time)  
      Catch
         Console.WriteLine("Unable to find {0}.", tzName)
      End Try   
   End Sub   
End Module

Beachten Sie Folgendes: Wenn diese Addition einfach für den DateTimeOffset Wert ausgeführt wird, ohne Sie zuerst in die UTC zu umrechnen, gibt das Ergebnis den richtigen Zeitpunkt wieder, aber die Abweichung spiegelt nicht die der festgelegten Zeitzone für diese Uhrzeit wider.Note that if this addition is simply performed on the DateTimeOffset value without first converting it to UTC, the result reflects the correct point in time but its offset does not reflect that of the designated time zone for that time.

Kompilieren des CodesCompiling the code

Für dieses Beispiel benötigen Sie Folgendes:This example requires:

  • , Dass der System Namespace mit der using-Anweisung importiert werden soll C# (erforderlich im Code).That the System namespace be imported with the using statement (required in C# code).

Siehe auchSee also