Delen via


Procedure: Tijdzones gebruiken in datum- en tijdberekeningen

Normaal gesproken worden bij het uitvoeren van datum- en tijdberekeningen DateTime of DateTimeOffset -waarden geen regels voor het aanpassen van tijdzones weergegeven. Dit geldt zelfs wanneer de tijdzone van de datum- en tijdwaarde duidelijk identificeerbaar is (bijvoorbeeld wanneer de Kind eigenschap is ingesteld op Local). In dit onderwerp wordt beschreven hoe u rekenkundige bewerkingen uitvoert op datum- en tijdwaarden die deel uitmaken van een bepaalde tijdzone. De resultaten van de rekenkundige bewerkingen weerspiegelen de aanpassingsregels van de tijdzone.

Aanpassingsregels toepassen op rekenkundige datum- en tijdberekeningen

  1. Implementeer een methode om een datum- en tijdwaarde nauw te koppelen aan de tijdzone waartoe deze behoort. Declareer bijvoorbeeld een structuur die zowel de datum- als tijdwaarde en de tijdzone bevat. In het volgende voorbeeld wordt deze methode gebruikt om een waarde te koppelen aan de DateTime tijdzone.

    // 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. Converteer een tijd naar Coordinated Universal Time (UTC) door de ConvertTimeToUtc methode of de ConvertTime methode aan te roepen.

  3. Voer de rekenkundige bewerking uit op de UTC-tijd.

  4. Converteer de tijd van UTC naar de bijbehorende tijdzone van de oorspronkelijke tijd door de methode aan te TimeZoneInfo.ConvertTime(DateTime, TimeZoneInfo) roepen.

Opmerking

In het volgende voorbeeld worden twee uur en dertig minuten toegevoegd aan 9 maart 2008 om 1:30 uur Central Standard Time. De overgang van de tijdzone naar zomertijd vindt dertig minuten later plaats om 2:00 uur op 9 maart 2008. Omdat het voorbeeld de vier stappen in de vorige sectie volgt, wordt de resulterende tijd correct gerapporteerd als 5:00 uur op 9 maart 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

Beide DateTime en DateTimeOffset waarden worden losgekoppeld van elke tijdzone waartoe ze kunnen behoren. Als u datum- en tijdberekeningen wilt uitvoeren op een manier die automatisch de aanpassingsregels van een tijdzone toepast, moet de tijdzone waartoe een datum- en tijdwaarde behoort, onmiddellijk identificeerbaar zijn. Dit betekent dat een datum en tijd en de bijbehorende tijdzone nauw moeten worden gekoppeld. Er zijn verschillende manieren om dit te doen, waaronder de volgende:

  • Stel dat alle tijden die in een toepassing worden gebruikt, deel uitmaken van een bepaalde tijdzone. Hoewel deze aanpak in sommige gevallen geschikt is, biedt deze aanpak beperkte flexibiliteit en mogelijk beperkte draagbaarheid.

  • Definieer een type dat een datum en tijd nauw koppelt aan de bijbehorende tijdzone door beide als velden van het type op te geven. Deze methode wordt gebruikt in het codevoorbeeld, waarmee een structuur wordt gedefinieerd voor het opslaan van de datum en tijd en de tijdzone in twee lidvelden.

In het voorbeeld ziet u hoe u rekenkundige bewerkingen kunt uitvoeren op DateTime waarden, zodat regels voor het aanpassen van tijdzones worden toegepast op het resultaat. DateTimeOffset Waarden kunnen echter net zo eenvoudig worden gebruikt. In het volgende voorbeeld ziet u hoe de code in het oorspronkelijke voorbeeld kan worden aangepast voor gebruik DateTimeOffset in plaats van DateTime waarden.

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

Houd er rekening mee dat als deze toevoeging gewoon wordt uitgevoerd op de DateTimeOffset waarde zonder deze eerst te converteren naar UTC, het resultaat het juiste tijdstip weerspiegelt, maar de offset ervan niet die van de aangewezen tijdzone voor die tijd.

Zie ook