Vorgehensweise: Erstellen von Zeitzonen mit Anpassungsregeln

Die genauen Zeitzoneninformationen, die von einer Anwendung benötigt werden, können aus mehreren Gründen nicht auf einem bestimmten System vorhanden sein:

  • Die Zeitzone wurde nie in der Registrierung des lokalen Systems definiert.

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

  • Die Zeitzone enthält keine präzisen Informationen zu Zeitzonenanpassungen für einen bestimmten, in der Vergangenheit liegenden Zeitraum.

In diesen Fällen können Sie die CreateCustomTimeZone-Methode aufrufen, um die Zeitzone zu definieren, die von Ihrer Anwendung benötigt wird. Sie können die Überladungen dieser Methode verwenden, um eine Zeitzone mit oder ohne Anpassungsregeln zu erstellen. Wenn die Zeitzone die Sommerzeit unterstützt, können Sie Anpassungen mit festen oder dynamischen Anpassungsregeln definieren. (Definitionen dieser Begriffe finden Sie im Abschnitt „Zeitzonenterminologie“ in der Zeitzonenübersicht.)

Wichtig

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

In diesem Artikel erfahren Sie, wie Sie eine Zeitzone mit Anpassungsregeln erstellen. Unter Erstellen von Zeitzonen ohne Anpassungsregeln finden Sie weitere Informationen zum Erstellen einer Zeitzone, die keine Zeitanpassungsregeln für die Sommerzeit unterstützt.

Erstellen einer Zeitzone mit gleitenden Anpassungsregeln

  1. Für jede Anpassung (d. h. jede Umstellung von der Standardzeit und auf diese zurück für ein bestimmtes Zeitintervall) sind die folgenden Schritte nötig:

    1. Definieren Sie den Startzeitpunkt für die Zeitzonenanpassung.

      Sie müssen die Methode TimeZoneInfo.TransitionTime.CreateFloatingDateRule aufrufen und dieser einen DateTime-Wert übergeben, der die Uhrzeit der Umstellung definiert, einen Integerwert, der den Monat der Umstellung definiert, einen weiteren Integerwert, der die Woche der Umstellung definiert, und einen DayOfWeek-Wert, der den Tag der Woche definiert, an dem die Umstellung erfolgt. Dieser Methodenaufruf instanziiert ein TimeZoneInfo.TransitionTime-Objekt.

    2. Definieren Sie den Endzeitpunkt für die Zeitzonenanpassung. Dies erfordert einen weiteren 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 das effektive Start- und Enddatum der Anpassung, ein TimeSpan-Objekt, das die Dauer der Umstellung definiert, und die beiden TimeZoneInfo.TransitionTime-Objekte, die definieren, wann die Umstellung auf die Sommer- oder Winterzeit stattfindet. Dieser Methodenaufruf instanziiert ein TimeZoneInfo.AdjustmentRule-Objekt.

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

  2. Definieren Sie den Anzeigenamen der Zeitzone. Der Anzeigename folgt einem Standardformat, bei dem die Differenz der Zeitzone zur koordinierten Weltzeit (UTC) in Klammern eingeschlossen ist und auf die eine Zeichenfolge folgt, die die Zeitzone, mindestens eine Stadt in der Zeitzone oder mindestens ein Land oder eine Region in der Zeitzone angibt.

  3. Definieren Sie den Namen der Standardzeit der Zeitzone. In der Regel wird diese Zeichenfolge auch als 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 die Differenz der Zeitzone zur koordinierten Weltzeit definiert. Zeitzonen mit Uhrzeiten, die hinter der koordinierten Weltzeit liegen, weisen eine positive Differenz auf. Zeitzonen mit Uhrzeiten, die vor der koordinierten Weltzeit liegen, weisen eine negative Differenz 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 die Zeitzone „Central Standard Time“ für die USA definiert, die Anpassungsregeln für eine Vielzahl von Zeitintervallen von 1918 bis heute enthält.

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

Die in diesem Beispiel erstellte Zeitzone verfügt über mehrere Anpassungsregeln. Achten Sie darauf, dass sich die effektiven Start- und Endtermine einer Anpassungsregel nicht mit den Datumsangaben einer anderen Anpassungsregel überschneiden. Wenn es eine Überlappung gibt, wird eine InvalidTimeZoneException-Ausnahme ausgelöst.

Bei gleitenden 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.

Beim Erstellen des Arrays aus TimeZoneInfo.AdjustmentRule-Objekten, die TimeZoneInfo.CreateCustomTimeZone(String, TimeSpan, String, String, String, TimeZoneInfo+AdjustmentRule[]) im Methodenaufruf verwendet werden sollen, könnte der Code das Array auf die Größe initialisieren, die durch die Anzahl der für die Zeitzone zu erstellenden Anpassungen erforderlich ist. Stattdessen ruft dieses Codebeispiel die Add-Methode auf, um jede Anpassungsregel einer generischen List<T>-Collection aus TimeZoneInfo.AdjustmentRule-Objekten hinzuzufügen. Der Code ruft dann die CopyTo-Methode auf, um die Member dieser Collection in das Array zu kopieren.

Im Beispiel wird auch die CreateFixedDateRule-Methode verwendet, um Anpassungen mit festem Datum zu definieren. Dieser Vorgang ähnelt dem Aufrufen der CreateFloatingDateRule-Methode, mit dem Unterschied, dass nur die Uhrzeit, der Monat und der Tag der Umstellungsparameter erforderlich sind.

Das Beispiel kann mithilfe von Code wie dem folgenden getestet werden:

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

Kompilieren des Codes

Für dieses Beispiel benötigen Sie Folgendes:

  • Dass die folgenden Namespaces importiert werden:

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

Weitere Informationen