Postupy: Vytváření časových pásem s pravidly úpravy

Přesné informace o časovém pásmu, které aplikace vyžaduje, nemusí být přítomny v určitém systému z několika důvodů:

  • Časové pásmo nebylo nikdy definováno v registru místního systému.

  • Data o časovém pásmu byla změněna nebo odebrána z registru.

  • Časové pásmo nemá přesné informace o úpravách časového pásma pro určité historické období.

V těchto případech můžete volat metodu CreateCustomTimeZone pro definování časového pásma vyžadovaného vaší aplikací. Přetížení této metody můžete použít k vytvoření časového pásma s pravidly úprav nebo bez této metody. Pokud časové pásmo podporuje letní čas, můžete definovat úpravy pomocí pevných nebo plovoucích pravidel úprav. (Definice těchto termínů najdete v části Terminologie časového pásma v části Přehled časového pásma.)

Důležité

Vlastní časová pásma vytvořená voláním CreateCustomTimeZone metody nejsou přidána do registru. Místo toho lze k nim přistupovat pouze prostřednictvím odkazu na objekt vrácený voláním CreateCustomTimeZone metody.

Toto téma ukazuje, jak vytvořit časové pásmo s pravidly úprav. Chcete-li vytvořit časové pásmo, které nepodporuje pravidla úpravy letního času, přečtěte si článek Postupy: Vytvoření časových pásem bez pravidel úpravy.

Vytvoření časového pásma s plovoucími pravidly úpravy

  1. Pro každou úpravu (to znamená pro každý přechod mimo a zpět na standardní čas v určitém časovém intervalu) postupujte takto:

    1. Definujte počáteční čas přechodu pro úpravu časového pásma.

      Musíte volat metodu TimeZoneInfo.TransitionTime.CreateFloatingDateRule a předat ji DateTime hodnotu, která definuje čas přechodu, celočíselnou hodnotu, která definuje měsíc přechodu, celočíselnou hodnotu, která definuje týden, ve kterém přechod nastane, a DayOfWeek hodnotu, která definuje den v týdnu, ve kterém se přechod vyskytuje. Tato metoda volá instanci objektu TimeZoneInfo.TransitionTime .

    2. Definujte koncový čas přechodu pro úpravy časového pásma. To vyžaduje další volání TimeZoneInfo.TransitionTime.CreateFloatingDateRule metody. Volání této metody vytvoří instanci druhého TimeZoneInfo.TransitionTime objektu.

    3. Zavolejte metodu CreateAdjustmentRule a předejte jí efektivní počáteční a koncové datum úpravy, TimeSpan objekt, který definuje dobu přechodu, a dva TimeZoneInfo.TransitionTime objekty, které definují, kdy dojde k přechodu do a z letního času. Tato metoda volá instanci objektu TimeZoneInfo.AdjustmentRule .

    4. TimeZoneInfo.AdjustmentRule Přiřaďte objekt k poli TimeZoneInfo.AdjustmentRule objektů.

  2. Definujte zobrazovaný název časového pásma. Zobrazovaný název se řídí poměrně standardním formátem, ve kterém je posun časového pásma od koordinovaného univerzálního času (UTC) uzavřený do závorek a následuje řetězec, který identifikuje časové pásmo, jedno nebo více měst v časovém pásmu nebo jednu nebo více zemí nebo oblastí v časovém pásmu.

  3. Definujte název standardního času časového pásma. Tento řetězec se obvykle používá také jako identifikátor časového pásma.

  4. Definujte název letního času časového pásma.

  5. Pokud chcete použít jiný identifikátor než standardní název časového pásma, definujte identifikátor časového pásma.

  6. Vytvořte instanci objektu TimeSpan , který definuje posun časového pásma od času UTC. Časová pásma s časy pozdějšími než UTC mají kladný posun. Časová pásma s časy dřívějšími než UTC mají záporný posun.

  7. TimeZoneInfo.CreateCustomTimeZone(String, TimeSpan, String, String, String, TimeZoneInfo+AdjustmentRule[]) Voláním metody vytvořte instanci nového časového pásma.

Příklad

Následující příklad definuje centrální standardní časové pásmo pro USA, které obsahuje pravidla úprav pro různé časové intervaly od roku 1918 do současnosti.

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)

Časové pásmo vytvořené v tomto příkladu má několik pravidel úpravy. Je třeba dbát na to, aby se efektivní počáteční a koncové datum jakéhokoli pravidla úpravy nepřekrývaly s daty jiného pravidla úpravy. Pokud dojde k překrývání, vyvolá se chyba InvalidTimeZoneException .

V případě pravidel úpravy s plovoucí desetinou čárkou se hodnota 5 předá week parametru CreateFloatingDateRule metody, který indikuje, že k přechodu dochází v posledním týdnu konkrétního měsíce.

Při vytváření pole TimeZoneInfo.AdjustmentRule objektů, které se mají použít ve TimeZoneInfo.CreateCustomTimeZone(String, TimeSpan, String, String, String, TimeZoneInfo+AdjustmentRule[]) volání metody, může kód inicializovat pole na velikost požadovanou počtem úprav, které se mají vytvořit pro časové pásmo. Místo toho tento příklad kódu volá metodu Add pro přidání každého pravidla úpravy do obecné List<T> kolekce TimeZoneInfo.AdjustmentRule objektů. Kód pak zavolá metodu CopyTo , která zkopíruje členy této kolekce do pole.

Příklad také používá metodu CreateFixedDateRule k definování pevných úprav data. Podobá se volání CreateFloatingDateRule metody s tím rozdílem, že vyžaduje pouze čas, měsíc a den přechodu parametrů.

Příklad je možné otestovat pomocí kódu, jako je následující:

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                            

Zkompilování kódu

Tento příklad vyžaduje:

  • Importují se následující obory názvů:

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

Viz také