Freigeben über


Gewusst wie: Erstellen von Zeitzonen mit Anpassungsregeln

Die genauen Zeitzonendaten, die eine Anwendung benötigt, können aus mehreren Gründen auf einem bestimmten System nicht vorhanden sein:

  • Die Zeitzone wurde zuvor noch nicht in der Registrierung des lokalen Systems definiert.

  • Daten der Zeitzone wurden geändert oder aus der Registrierung entfernt.

  • Die Zeitzone weist keine genauen Informationen über Zeitzonenanpassungen für einen bestimmten historischen Zeitraum auf.

In diesen Fällen können Sie die CreateCustomTimeZone-Methode aufrufen, um die von der Anwendung benötigte Zeitzone zu definieren. Sie können die Überladungen dieser Methode zum Erstellen einer Zeitzone mit oder ohne Anpassungsregeln verwenden. Wenn die Zeitzone die Sommerzeit unterstützt, können Sie Anpassungen mit festen oder beweglichen Anpassungsregeln definieren. (Definitionen dieser Begriffe finden Sie im Abschnitt "Zeitzonenterminologie" unter Übersicht über Zeitzonen.)

Wichtiger HinweisWichtig

Benutzerdefinierte Zeitzonen, die durch Aufrufen der CreateCustomTimeZone-Methode erstellt werden, werden nicht zur Registrierung hinzugefügt.Stattdessen kann nur über den Objektverweis, der vom Aufruf der CreateCustomTimeZone-Methode zurückgegeben wird, darauf zugegriffen werden.

In diesem Thema wird erläutert, wie Sie eine Zeitzone mit Anpassungsregeln erstellen. Informationen zum Erstellen einer Zeitzone, die keine Anpassungsregeln für die Sommerzeit unterstützt, finden Sie unter Gewusst wie: Erstellen von Zeitzonen ohne Anpassungsregeln.

So erstellen Sie eine Zeitzone mit beweglichen Anpassungsregeln

  1. Gehen Sie für jede Anpassung (d. h. für die Umstellung von und zurück auf Normalzeit über ein bestimmtes Zeitintervall) wie folgt vor:

    1. Definieren Sie den Beginn der Umstellungszeit für die Zeitzonenanpassung.

      Sie müssen die TimeZoneInfo.TransitionTime.CreateFloatingDateRule-Methode aufrufen und einen DateTime-Wert an sie übergeben, der die Uhrzeit der Umstellung, eine Ganzzahl für den Monat, eine Ganzzahl für die Woche und einen DayOfWeek-Wert für den Wochentag der Umstellung definiert. Dieser Methodenaufruf instanziiert ein TimeZoneInfo.TransitionTime-Objekt.

    2. Definieren Sie das Ende der Umstellungszeit für die Zeitzonenanpassung. Dies erfordert einen erneuten Aufruf der TimeZoneInfo.TransitionTime.CreateFloatingDateRule-Methode. Dieser Methodenaufruf instanziiert ein zweites TimeZoneInfo.TransitionTime-Objekt.

    3. Rufen Sie die CreateAdjustmentRule-Methode auf, und übergeben Sie ihr die effektiven Anfangs- und Enddaten der Anpassung, ein TimeSpan-Objekt, das die Dauer der Umstellung angibt, und zwei TimeZoneInfo.TransitionTime-Objekte, mit denen definiert wird, wann die Umstellung auf und von Sommerzeit erfolgt. Dieser Methodenaufruf instanziiert ein TimeZoneInfo.AdjustmentRule-Objekt.

    4. Weisen Sie das TimeZoneInfo.AdjustmentRule-Objekt einem Array von TimeZoneInfo.AdjustmentRule-Objekten zu.

  2. Definieren Sie den Anzeigenamen der Zeitzone. Der Anzeigename folgt einem gewissen Standardformat. Hierbei wird der Offset der Zeitzone von der koordinierten Weltzeit (Coordinated Universal Time, UTC) in Klammern eingeschlossen, gefolgt von einer Zeichenfolge, die die Zeitzone, einen oder mehrere Orte in der Zeitzone oder ein oder mehrere Länder oder Regionen in der Zeitzone identifiziert.

  3. Definieren Sie den Namen der Normalzeit der Zeitzone. Diese Zeichenfolge wird normalerweise auch als der Bezeichner der Zeitzone verwendet.

  4. Definieren Sie den Namen der Sommerzeit der Zeitzone.

  5. Wenn Sie einen anderen Bezeichner als den Standardnamen der Zeitzone verwenden möchten, definieren Sie den Zeitzonenbezeichner.

  6. Instanziieren Sie ein TimeSpan-Objekt, das den Offset der Zeitzone von UTC definiert. Zeitzonen mit Uhrzeiten, die nach UTC liegen, weisen einen positiven Offset auf. Zeitzonen mit Uhrzeiten, die vor UTC liegen, weisen einen negativen Offset auf.

  7. Rufen Sie die TimeZoneInfo.CreateCustomTimeZone(String, TimeSpan, String, String, String, TimeZoneInfo.AdjustmentRule[])-Methode auf, um die neue Zeitzone zu instanziieren.

Beispiel

Im folgenden Beispiel wird eine Central Normalzeit-Zeitzone für die USA definiert, die Anpassungsregeln für verschiedene Zeitintervalle von 1918 bis heute umfasst.

Dim cst As TimeZoneInfo
' Declare necessary TimeZoneInfo.AdjustmentRule objects for time zone
Dim delta As New TimeSpan(1, 0, 0)
Dim adjustment As TimeZoneInfo.AdjustmentRule
Dim adjustmentList As New List(Of TimeZoneInfo.AdjustmentRule)
' Declare transition time variables to hold transition time information
Dim transitionRuleStart, transitionRuleEnd As TimeZoneInfo.TransitionTime

' Define new Central Standard Time zone 6 hours earlier than UTC
' Define rule 1 (for 1918-1919)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#02:00:00AM#, 03, 05, DayOfWeek.Sunday)
transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#02:00:00AM#, 10, 05, DayOfWeek.Sunday) 
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1918#, #12/31/1919#, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment) 
' Define rule 2 (for 1942)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(#2:00:00AM#, 02, 09)
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1942#, #12/31/1942#, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment)
' Define rule 3 (for 1945)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(#11:00:00PM#, 08, 14)
transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFixedDateRule(#2:00:00AM#, 09, 30)
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1945#, #12/31/1945#, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment)
' Define end rule (for 1967-2006)
transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#02:00:00AM#, 10, 5, DayOfWeek.Sunday)
' Define rule 4 (for 1967-73)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#2:00:00AM#, 04, 05, DayOfWeek.Sunday)
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1967#, #12/31/1973#, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment)
' Define rule 5 (for 1974 only)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(#2:00:00AM#, 01, 06)
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1974#, #12/31/1974#, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment)
' Define rule 6 (for 1975 only)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(#2:00:00AM#, 02, 23)
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1975#, #12/31/1975#, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment)
' Define rule 7 (1976-1986)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#2:00:00AM#, 04, 05, DayOfWeek.Sunday)
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1976#, #12/31/1986#, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment)
' Define rule 8 (1987-2006)  
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#2:00:00AM#, 04, 01, DayOfWeek.Sunday)
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1987#, #12/31/2006#, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment)
' Define rule 9 (2007- )  
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#2:00:00AM#, 03, 02, DayOfWeek.Sunday)
transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#2:00:00AM#, 11, 01, DayOfWeek.Sunday)
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/2007#, Date.MaxValue.Date, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment)

' Convert list of adjustment rules to an array
Dim adjustments(adjustmentList.Count - 1) As TimeZoneInfo.AdjustmentRule
adjustmentList.CopyTo(adjustments)

cst = TimeZoneInfo.CreateCustomTimeZone("Central Standard Time", New TimeSpan(-6, 0, 0), _
      "(GMT-06:00) Central Time (US Only)", "Central Standard Time", _
      "Central Daylight Time", adjustments)
TimeZoneInfo cst;
// Declare necessary TimeZoneInfo.AdjustmentRule objects for time zone
TimeSpan delta = new TimeSpan(1, 0, 0);
TimeZoneInfo.AdjustmentRule adjustment;
List<TimeZoneInfo.AdjustmentRule> adjustmentList = new List<TimeZoneInfo.AdjustmentRule>();
// Declare transition time variables to hold transition time information
TimeZoneInfo.TransitionTime transitionRuleStart, transitionRuleEnd;

// Define new Central Standard Time zone 6 hours earlier than UTC
// Define rule 1 (for 1918-1919)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 03, 05, DayOfWeek.Sunday);
transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 10, 05, DayOfWeek.Sunday); 
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1918, 1, 1), new DateTime(1919, 12, 31), delta, 
                                                           transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment); 
// Define rule 2 (for 1942)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, 2, 0, 0), 02, 09);
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1942, 1, 1), new DateTime(1942, 12, 31), 
                                                           delta, transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment);
// Define rule 3 (for 1945)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, 23, 0, 0), 08, 14);
transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, 2, 0, 0), 09, 30);
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1945, 1, 1), new DateTime(1945, 12, 31), 
                                                           delta, transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment);
// Define end rule (for 1967-2006)
transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 10, 5, DayOfWeek.Sunday);
// Define rule 4 (for 1967-73)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 04, 05, DayOfWeek.Sunday);
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1967, 1, 1), new DateTime(1973, 12, 31), 
                                                           delta, transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment);
// Define rule 5 (for 1974 only)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, 2, 0, 0), 01, 06);
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1974, 1, 1), new DateTime(1974, 12, 31), 
                                                           delta, transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment);
// Define rule 6 (for 1975 only)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, 2, 0, 0), 02, 23);
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1975, 1, 1), new DateTime(1975, 12, 31), 
                                                           delta, transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment);
// Define rule 7 (1976-1986)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 04, 05, DayOfWeek.Sunday);
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1976, 1, 1), new DateTime(1986, 12, 31), 
                                                           delta, transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment);
// Define rule 8 (1987-2006)  
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 04, 01, DayOfWeek.Sunday);
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1987, 1, 1), new DateTime(2006, 12, 31), 
                                                           delta, transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment);
// Define rule 9 (2007- )  
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 03, 02, DayOfWeek.Sunday);
transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 11, 01, DayOfWeek.Sunday);
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(2007, 1, 1), DateTime.MaxValue.Date, 
                                                           delta, transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment);

// Convert list of adjustment rules to an array
TimeZoneInfo.AdjustmentRule[] adjustments = new TimeZoneInfo.AdjustmentRule[adjustmentList.Count];
adjustmentList.CopyTo(adjustments);

cst = TimeZoneInfo.CreateCustomTimeZone("Central Standard Time", new TimeSpan(-6, 0, 0), 
      "(GMT-06:00) Central Time (US Only)", "Central Standard Time", 
      "Central Daylight Time", adjustments);

Die in diesem Beispiel erstellte Zeitzone hat mehrere Anpassungsregeln. Sie müssen vor allem darauf achten, dass sich die effektiven Anfangs- und Enddaten einer Anpassungsregel nicht mit denen einer anderen Anpassungsregel überschneiden. Wenn eine Überschneidung vorliegt, wird eine InvalidTimeZoneException ausgelöst.

Bei beweglichen Anpassungsregeln wird der Wert 5 an den week-Parameter der CreateFloatingDateRule-Methode übergeben, um anzugeben, dass die Umstellung in der letzten Woche eines bestimmten Monats erfolgt.

Indem das Array von TimeZoneInfo.AdjustmentRule-Objekten zur Verwendung mit dem TimeZoneInfo.CreateCustomTimeZone(String, TimeSpan, String, String, String, TimeZoneInfo.AdjustmentRule[])-Methodenaufruf erstellt wird, könnte der Code das Array in der Größe initialisieren, die für die Anzahl der Anpassungsregeln, die für die Zeitzone erstellt werden sollen, notwendig ist. Dieser Code ruft stattdessen die Add-Methode auf, mit der die einzelnen Anpassungsregeln einer allgemeinen List<T>-Auflistung von TimeZoneInfo.AdjustmentRule-Objekten hinzugefügt werden. Im Code wird dann die CopyTo-Methode aufgerufen, um die Member dieser Auflistung in das Array zu kopieren.

Im Beispiel wird außerdem die CreateFixedDateRule-Methode verwendet, um Anpassungen mit festem Datum zu definieren. Dies ähnelt dem Aufrufen der CreateFloatingDateRule-Methode, wobei jedoch nur die Zeit, der Monat und der Tag der Umstellungsparameter erforderlich sind.

Das Beispiel kann mit folgendem Code getestet werden:

Dim est As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")

Dim pastDate1 As Date = #2/11/1942#
Console.WriteLine("Is {0} daylight saving time: {1}", pastDate1, _
                  cst.IsDaylightSavingTime(pastDate1))

Dim pastDate2 As Date = #10/29/1967 1:30AM#
Console.WriteLine("Is {0} ambiguous: {1}", pastDate2, _
                  cst.IsAmbiguousTime(pastDate2))

Dim pastDate3 As Date = #1/7/1974 2:59AM#
Console.WriteLine("{0} {1} is {2} {3}", pastDate3, _
                  IIf(est.IsDaylightSavingTime(pastDate3), _
                      est.DaylightName, est.StandardName), _
                  TimeZoneInfo.ConvertTime(pastDate3, est, cst), _ 
                  IIf(cst.IsDaylightSavingTime(TimeZoneInfo.ConvertTime(pastDate3, est, cst)), _
                      cst.DaylightName, cst.StandardName)) 
'
' This code produces the following output to the console:
' 
'    Is 2/11/1942 12:00:00 AM daylight saving time: True
'    Is 10/29/1967 1:30:00 AM ambiguous: True
'    1/7/1974 2:59:00 AM Eastern Standard Time is 1/7/1974 2:59:00 AM Central Daylight Time                            
TimeZoneInfo est = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

DateTime pastDate1 = new DateTime(1942, 2, 11);
Console.WriteLine("Is {0} daylight saving time: {1}", pastDate1, 
                  cst.IsDaylightSavingTime(pastDate1));

DateTime pastDate2 = new DateTime(1967, 10, 29, 1, 30, 00);
Console.WriteLine("Is {0} ambiguous: {1}", pastDate2, 
                  cst.IsAmbiguousTime(pastDate2));

DateTime pastDate3 = new DateTime(1974, 1, 7, 2, 59, 00);
Console.WriteLine("{0} {1} is {2} {3}", pastDate3, 
                  est.IsDaylightSavingTime(pastDate3) ? 
                      est.DaylightName : est.StandardName, 
                  TimeZoneInfo.ConvertTime(pastDate3, est, cst),  
                  cst.IsDaylightSavingTime(TimeZoneInfo.ConvertTime(pastDate3, est, cst)) ?
                      cst.DaylightName : cst.StandardName);
//
// This code produces the following output to the console:
// 
//    Is 2/11/1942 12:00:00 AM daylight saving time: True
//    Is 10/29/1967 1:30:00 AM ambiguous: True
//    1/7/1974 2:59:00 AM Eastern Standard Time is 1/7/1974 2:59:00 AM Central Daylight Time                            

Kompilieren des Codes

Für dieses Beispiel ist Folgendes erforderlich:

  • Dem Projekt muss ein Verweis auf System.Core.dll hinzugefügt werden.

  • Die folgenden Namespaces müssen importiert werden:

    Imports System.Collections.Generic
    Imports System.Collections.ObjectModel
    
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    

Siehe auch

Aufgaben

Gewusst wie: Erstellen von Zeitzonen ohne Anpassungsregeln

Konzepte

Übersicht über Zeitzonen

Weitere Ressourcen

Datumsangaben, Uhrzeiten und Zeitzonen