HOW TO:建立有調整規則的時區
更新:2007 年 11 月
特定系統可能基於以下原因,而沒有應用程式所需的精確的時區資訊:
本機系統登錄中從未定義這個時區。
時區的資料已被修改或從登錄中移除。
這個時區並沒有特定歷史期間的時區調整精確資訊。
在這種情況下,您可以呼叫 CreateCustomTimeZone 方法以定義應用程式所需的時區。您可以使用這個方法的多載,以建立包含或不含調整規則的時區。如果該時區支援日光節約時間,您可以使用固定或浮動調整規則來定義調整方式 (如需這些用語的定義,請參閱時區概觀的「時區用語」一節)。
重要事項: |
---|
呼叫 CreateCustomTimeZone 方法所建立的自訂時區不會新增至登錄中。只能透過 CreateCustomTimeZone 方法呼叫所傳回的物件參考才能存取。 |
本主題說明如何建立時區和調整規則。如果要建立不支援日光節約時間調整規則的時區,請參閱 HOW TO:建立沒有調整規則的時區。
建立採用浮動調整規則的時區
對每一個調整方法 (就是,標準時間與特定時間間隔的來回轉換) 執行下列步驟:
定義時區調整開始轉換的時間。
您必須呼叫 TimeZoneInfo.TransitionTime.CreateFloatingDateRule 方法,並將下列值傳送給方法:定義轉換時間的 DateTime 值、定義轉換月份的整數值、定義轉換週的整數值,以及定義轉換日的 DayOfWeek 值。這個方法呼叫會將 TimeZoneInfo.TransitionTime 物件個體化。
定義時區調整結束轉換的時間。這麼做必須要再次呼叫 TimeZoneInfo.TransitionTime.CreateFloatingDateRule 方法。這個方法呼叫會將第二個 TimeZoneInfo.TransitionTime 物件個體化。
呼叫 CreateAdjustmentRule 方法,並將下列值傳送給方法:調整的有效開始及結束日期、定義轉換時間長度的 TimeSpan 物件,以及兩個定義來回轉換日光節約時間發生時間的 TimeZoneInfo.TransitionTime 物件。這個方法呼叫會將 TimeZoneInfo.AdjustmentRule 物件個體化。
將 TimeZoneInfo.AdjustmentRule 物件指派給 TimeZoneInfo.AdjustmentRule 物件的陣列。
定義時區的顯示名稱。顯示名稱遵循相當程度的標準格式,其中時區的 Coordinated Universal Time (UTC) 位移會包含在括號中,後面接著識別時區的字串、該時區的一或多個城市,或是該時區的一或多個國家或地區。
定義時區的標準時間之名稱。通常,這個字串也會當成時區的識別項使用。
定義時區的日光節約時間名稱。
如果您要使用和時區的標準名稱不同的識別項,請定義時區識別項。
將定義時區的 UTC 位移之 TimeSpan 物件個體化。時間較 UTC 晚的時區,位移值是正的。時間較 UTC 早的時區,位移值是負的。
呼叫 TimeZoneInfo.CreateCustomTimeZone(String, TimeSpan, String, String, String, array<TimeZoneInfo.AdjustmentRule[]) 方法,將新時區個體化。
範例
下列範例會定義美國的「中央標準時間」區,內含自 1918 年至今的各種時間間隔的調整規則。
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);
本範例中所建立的時區有多重調整規則。請特別小心,以確保任何調整規則的有效開始及結束日期不會與其他調整規則的日期重疊。如果重疊,就會擲回 InvalidTimeZoneException。
如果是浮動調整規則,會將值 5 傳送給 CreateFloatingDateRule 方法的 week 參數,以指出轉換是在特定月份的最後一週發生的。
在建立 TimeZoneInfo.AdjustmentRule 物件的陣列以使用於 TimeZoneInfo.CreateCustomTimeZone(String, TimeSpan, String, String, String, array<TimeZoneInfo.AdjustmentRule[]) 方法呼叫時,程式碼可以將陣列個體化,使陣列的大小和時區要建立之調整數目所要求的大小一樣。這個程式碼範例會呼叫 Add 方法,將每一個調整規則新增至 TimeZoneInfo.AdjustmentRule 物件的泛型 List<T> 集合。然後程式碼會呼叫 CopyTo 方法,將集合的成員複製至陣列。
這個範例也會使用 CreateFixedDateRule 方法來定義固定日期的調整。這麼做類似呼叫 CreateFloatingDateRule 方法,只不過它只需要轉換參數的時間、月份及日期。
本範例可以使用如下面的程式碼測試:
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
編譯程式碼
這個範例需要:
將 System.Core.dll 的參考加入至專案中。
匯入下列命名空間:
Imports System.Collections.Generic Imports System.Collections.ObjectModel
using System.Collections.Generic; using System.Collections.ObjectModel;