Instrukcje: Tworzenie stref czasowych przy użyciu reguł korygowania

Dokładne informacje o strefie czasowej wymagane przez aplikację mogą nie być obecne w określonym systemie z kilku powodów:

  • Strefa czasowa nigdy nie została zdefiniowana w rejestrze systemu lokalnego.

  • Dane dotyczące strefy czasowej zostały zmodyfikowane lub usunięte z rejestru.

  • Strefa czasowa nie ma dokładnych informacji o korektach strefy czasowej dla określonego okresu historycznego.

W takich przypadkach można wywołać metodę CreateCustomTimeZone , aby zdefiniować strefę czasową wymaganą przez aplikację. Za pomocą przeciążeń tej metody można utworzyć strefę czasową z regułami korekt lub bez nich. Jeśli strefa czasowa obsługuje czas letni, można zdefiniować korekty za pomocą reguł regulacji stałych lub zmiennoprzecinkowych. (Aby uzyskać definicje tych terminów, zobacz sekcję "Terminologia strefy czasowej" w temacie Omówienie strefy czasowej).

Ważne

Niestandardowe strefy czasowe utworzone przez wywołanie CreateCustomTimeZone metody nie są dodawane do rejestru. Zamiast tego można uzyskać do nich dostęp tylko za pośrednictwem odwołania do obiektu zwróconego CreateCustomTimeZone przez wywołanie metody.

W tym temacie pokazano, jak utworzyć strefę czasową z regułami korekt. Aby utworzyć strefę czasową, która nie obsługuje reguł regulacji czasu letniego, zobacz Instrukcje: tworzenie stref czasowych bez reguł korekty.

Aby utworzyć strefę czasową z regułami regulacji zmiennoprzecinkowych

  1. Dla każdej korekty (oznacza to, że dla każdego przejścia z i z powrotem do czasu standardowego w określonym przedziale czasu) wykonaj następujące czynności:

    1. Zdefiniuj czas rozpoczęcia przejścia dla korekty strefy czasowej.

      Należy wywołać metodę TimeZoneInfo.TransitionTime.CreateFloatingDateRule i przekazać jej DateTime wartość, która definiuje czas przejścia, wartość całkowitą, która definiuje miesiąc przejścia, wartość całkowitą, która definiuje tydzień, w którym następuje przejście, oraz DayOfWeek wartość definiującą dzień tygodnia, w którym następuje przejście. Ta metoda wywołuje wystąpienie TimeZoneInfo.TransitionTime obiektu.

    2. Zdefiniuj czas zakończenia przejścia dla korekty strefy czasowej. Wymaga to innego wywołania TimeZoneInfo.TransitionTime.CreateFloatingDateRule metody . Ta metoda wywołuje wystąpienie drugiego TimeZoneInfo.TransitionTime obiektu.

    3. Wywołaj metodę CreateAdjustmentRule i przekaż ją obowiązującą datę początkową i końcową TimeSpan korekty, obiekt, który definiuje czas przejścia, oraz dwa TimeZoneInfo.TransitionTime obiekty, które definiują, kiedy nastąpi przejście do i z czasu letniego. Ta metoda wywołuje wystąpienie TimeZoneInfo.AdjustmentRule obiektu.

    4. TimeZoneInfo.AdjustmentRule Przypisz obiekt do tablicy TimeZoneInfo.AdjustmentRule obiektów.

  2. Zdefiniuj nazwę wyświetlaną strefy czasowej. Nazwa wyświetlana jest zgodna z dość standardowym formatem, w którym przesunięcie strefy czasowej z uniwersalnego czasu koordynowanego (UTC) jest ujęte w nawiasy i następuje ciąg, który identyfikuje strefę czasową, co najmniej jedno miasto w strefie czasowej lub co najmniej jeden kraj lub regiony w strefie czasowej.

  3. Zdefiniuj nazwę standardowego czasu strefy czasowej. Zazwyczaj ten ciąg jest również używany jako identyfikator strefy czasowej.

  4. Zdefiniuj nazwę strefy czasowej (czas letni).

  5. Jeśli chcesz użyć innego identyfikatora niż standardowa nazwa strefy czasowej, zdefiniuj identyfikator strefy czasowej.

  6. TimeSpan Utwórz wystąpienie obiektu definiującego przesunięcie strefy czasowej z czasu UTC. Strefy czasowe z godzinami późniejszymi niż UTC mają dodatnie przesunięcie. Strefy czasowe z godzinami wcześniejszymi niż UTC mają ujemne przesunięcie.

  7. Wywołaj metodę , TimeZoneInfo.CreateCustomTimeZone(String, TimeSpan, String, String, String, TimeZoneInfo+AdjustmentRule[]) aby utworzyć wystąpienie nowej strefy czasowej.

Przykład

W poniższym przykładzie zdefiniowano centralną strefę czasową standardową dla Stany Zjednoczone, która obejmuje reguły korekty dla różnych interwałów czasowych od 1918 do obecnej.

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)

Strefa czasowa utworzona w tym przykładzie ma wiele reguł korekty. Należy zachować ostrożność, aby zapewnić, że obowiązujące daty rozpoczęcia i zakończenia każdej reguły korekty nie nakładają się na daty innej reguły korekty. Jeśli występuje nakładanie, zgłaszany jest element InvalidTimeZoneException .

W przypadku reguł korekt zmiennoprzecinkowych wartość 5 jest przekazywana do week parametru CreateFloatingDateRule metody, aby wskazać, że przejście ma miejsce w ostatnim tygodniu określonego miesiąca.

Tworząc tablicę TimeZoneInfo.AdjustmentRule obiektów do użycia w TimeZoneInfo.CreateCustomTimeZone(String, TimeSpan, String, String, String, TimeZoneInfo+AdjustmentRule[]) wywołaniu metody, kod może zainicjować tablicę do rozmiaru wymaganego przez liczbę korekt, które mają zostać utworzone dla strefy czasowej. Zamiast tego ten przykład kodu wywołuje metodę Add , aby dodać każdą regułę korekty do ogólnej List<T> kolekcji TimeZoneInfo.AdjustmentRule obiektów. Następnie kod wywołuje metodę CopyTo , aby skopiować elementy członkowskie tej kolekcji do tablicy.

W przykładzie użyto CreateFixedDateRule również metody do zdefiniowania korekt daty stałej. Jest to podobne do wywoływania CreateFloatingDateRule metody, z tą różnicą, że wymaga tylko czasu, miesiąca i dnia parametrów przejścia.

Przykład można przetestować przy użyciu kodu, takiego jak:

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                            

Kompilowanie kodu

Ten przykład wymaga:

  • Aby zaimportować następujące przestrzenie nazw:

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

Zobacz też