Aracılığıyla paylaş


Nasıl yapılır: Ayarlama kurallarıyla saat dilimleri oluşturma

Bir uygulamanın gerektirdiği kesin saat dilimi bilgileri belirli bir sistemde çeşitli nedenlerle mevcut olmayabilir:

  • Saat dilimi hiçbir zaman yerel sistemin kayıt defterinde tanımlanmadı.

  • Saat dilimiyle ilgili veriler değiştirildi veya kayıt defterinden kaldırıldı.

  • Saat dilimi, belirli bir tarihi dönem için saat dilimi ayarlamaları hakkında doğru bilgilere sahip değildir.

Bu gibi durumlarda, uygulamanızın gerektirdiği saat dilimini tanımlamak için CreateCustomTimeZone yöntemini çağırabilirsiniz. Ayarlama kuralları olan veya olmayan bir saat dilimi oluşturmak için bu yöntemin aşırı yüklemelerini kullanabilirsiniz. Saat dilimi gün ışığından yararlanma saatini destekliyorsa, düzeltmeleri sabit veya kayan ayarlama kurallarıyla tanımlayabilirsiniz. (Bu terimlerin tanımları için saat dilimine genel bakış "Saat Dilimi Terminolojisi" bölümüne bakın.)

Önemli

CreateCustomTimeZone yöntemi çağrılarak oluşturulan özel saat dilimleri kayıt defterine eklenmez. Bunun yerine, bunlara yalnızca CreateCustomTimeZone yöntem çağrısı tarafından döndürülen nesne başvurusu aracılığıyla erişilebilir.

Bu konuda, ayarlama kurallarıyla bir saat diliminin nasıl oluşturulacağı gösterilmektedir. Yaz saati ayarlama kurallarını desteklemeyen bir saat dilimi oluşturmak için bkz. Nasıl yapılır: Ayarlama Kuralları Olmadan Saat Dilimleri Oluşturma.

Kayan ayarlama kurallarıyla bir saat dilimi oluşturmak için

  1. Her ayarlama için (yani belirli bir zaman aralığında standart saatten uzak ve geri her geçiş için) aşağıdakileri yapın:

    1. Saat dilimi ayarlaması için başlangıç geçiş saatini tanımlayın.

      TimeZoneInfo.TransitionTime.CreateFloatingDateRule yöntemini çağırmanız ve geçişin zamanını tanımlayan bir DateTime değeri, geçişin ayını tanımlayan bir tamsayı değeri, geçişin gerçekleştiği haftayı tanımlayan bir tamsayı değeri ve geçişin gerçekleştiği haftanın gününü tanımlayan bir DayOfWeek değeri geçirmeniz gerekir. Bu yöntem çağrısı bir TimeZoneInfo.TransitionTime nesnesi örneği oluşturur.

    2. Saat dilimi ayarlaması için bitiş geçiş saatini tanımlayın. Bu, TimeZoneInfo.TransitionTime.CreateFloatingDateRule yöntemine başka bir çağrı gerektirir. Bu yöntem çağrısı ikinci bir TimeZoneInfo.TransitionTime nesnesi oluşturur.

    3. CreateAdjustmentRule yöntemini çağırın ve ayarlamanın etkin başlangıç ve bitiş tarihlerini, geçişteki süreyi tanımlayan bir TimeSpan nesnesi ve gün ışığından yararlanma saatine geçişlerin ne zaman gerçekleşeceğini tanımlayan iki TimeZoneInfo.TransitionTime nesnesini geçirin. Bu yöntem çağrısı bir TimeZoneInfo.AdjustmentRule nesnesi örneği oluşturur.

    4. TimeZoneInfo.AdjustmentRule nesnesini bir TimeZoneInfo.AdjustmentRule nesne dizisine atayın.

  2. Saat diliminin görünen adını tanımlayın. Görünen ad, saat diliminin Eşgüdümlü Evrensel Saat'ten (UTC) uzaklığının parantez içinde yer aldığı ve ardından saat dilimini, saat dilimindeki şehirlerden birini veya daha fazlasını ya da saat dilimindeki bir veya daha fazla ülkeyi veya bölgeyi tanımlayan bir dizenin takip ettiği oldukça standart bir biçimi izler.

  3. Saat diliminin standart saatinin adını tanımlayın. Bu dize genellikle saat dilimi tanımlayıcısı olarak da kullanılır.

  4. Saat diliminin yaz saatinin adını tanımlayın.

  5. Saat diliminin standart adından farklı bir tanımlayıcı kullanmak istiyorsanız saat dilimi tanımlayıcısını tanımlayın.

  6. UTC'den saat dilimi uzaklığını tanımlayan bir TimeSpan nesnesi örneği oluşturun. UTC'den sonraki saatlere sahip saat dilimlerinin uzaklığı pozitif olur. UTC'den önceki saatlere sahip saat dilimlerinin uzaklığı negatif olur.

  7. Yeni saat dilimini örneklemek için TimeZoneInfo.CreateCustomTimeZone(String, TimeSpan, String, String, String, TimeZoneInfo+AdjustmentRule[]) yöntemini çağırın.

Örnek

Aşağıdaki örnek, 1918'den günümüze kadar çeşitli zaman aralıkları için ayarlama kuralları içeren Abd için Merkezi Standart Saat dilimini tanımlar.

TimeZoneInfo cst;
// Declare necessary TimeZoneInfo.AdjustmentRule objects for time zone
TimeSpan delta = new(1, 0, 0);
TimeZoneInfo.AdjustmentRule adjustment;
List<TimeZoneInfo.AdjustmentRule> adjustmentList = [];
// 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)

Bu örnekte oluşturulan saat diliminde birden çok ayarlama kuralı vardır. Herhangi bir ayarlama kuralının geçerli başlangıç ve bitiş tarihlerinin başka bir ayarlama kuralının tarihleriyle çakışmadığından emin olmak için dikkatli olunmalıdır. Bir çakışma varsa, bir InvalidTimeZoneException fırlatılır.

Kayan ayarlama kuralları için 5 değeri, geçişin belirli bir ayın son haftası olduğunu göstermek için CreateFloatingDateRule yönteminin week parametresine geçirilir.

TimeZoneInfo.CreateCustomTimeZone(String, TimeSpan, String, String, String, TimeZoneInfo+AdjustmentRule[]) yöntem çağrısında kullanılacak TimeZoneInfo.AdjustmentRule nesne dizisi oluşturulurken kod, diziyi saat dilimi için oluşturulacak ayarlama sayısının gerektirdiği boyuta başlatabilir. Bunun yerine bu kod örneği, her ayarlama kuralını TimeZoneInfo.AdjustmentRule nesnelerden oluşan genel bir List<T> koleksiyonuna eklemek için Add yöntemini çağırır. Kod daha sonra bu koleksiyonun üyelerini diziye kopyalamak için CopyTo yöntemini çağırır.

Örnek ayrıca sabit tarih ayarlamalarını tanımlamak için CreateFixedDateRule yöntemini kullanır. Bu, yalnızca geçiş parametrelerinin saatini, ayını ve gününü gerektirmesi dışında CreateFloatingDateRule yöntemini çağırmaya benzer.

Örnek, aşağıdaki gibi bir kod kullanılarak test edilebilir:

TimeZoneInfo est = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

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

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

DateTime pastDate3 = new(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                            

Kodu derleme

Bu örnek şunları gerektirir:

  • Aşağıdaki ad alanlarının içe aktarılması önerilmektedir:

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

Ayrıca bkz.