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