この記事の英語版を表示するには、[英語] のチェック ボックスをオンにしてください。また、テキストにマウス ポインターを合わせると、ポップアップ ウィンドウに英語のテキストを表示することもできます。
翻訳
英語

方法 : 調整規則のあるタイム ゾーンを作成する

 

アプリケーションで必要な正確なタイム ゾーン情報が、次のような理由で特定のシステムに存在しない場合があります。

  • ローカル システムのレジストリでタイム ゾーンが定義されていない。

  • タイム ゾーンに関するデータがレジストリで変更または削除されている。

  • タイム ゾーンに、過去の特定の期間のタイム ゾーン調整に関する正確な情報がない。

このような場合は、CreateCustomTimeZone メソッドを呼び出して、アプリケーションで必要なタイム ゾーンを定義できます。 このメソッドのオーバーロードを使用すると、調整規則のあるタイム ゾーンまたは調整規則のないタイム ゾーンを作成できます。 タイム ゾーンが夏時間をサポートする場合は、固定調整規則または浮動調整規則の調整を定義できます。これらの用語の定義については、「タイム ゾーンの概要」の「タイム ゾーンの用語」の節を参照してください。

System_CAPS_important重要

CreateCustomTimeZone メソッドを呼び出すことで作成されるカスタム タイム ゾーンは、レジストリには追加されません。 カスタム タイム ゾーンには、CreateCustomTimeZone メソッドの呼び出しによって返されるオブジェクト参照を通してのみアクセスできます。

このトピックでは、調整規則のあるタイム ゾーンを作成する方法について説明します。 夏時間調整規則をサポートしないタイム ゾーンを作成する方法については、「方法 : 調整規則のないタイム ゾーンを作成する」を参照してください。

浮動調整規則のあるタイム ゾーンを作成するには

  1. 調整ごとに (つまり、特定の期間における標準時間からの切り替えと標準時間への切り替えのそれぞれについて)、次の操作を行います。

    1. タイム ゾーン調整の切り替え開始時刻を定義します。

      TimeZoneInfo.TransitionTime.CreateFloatingDateRule メソッドを呼び出して、切り替えの時刻を定義する DateTime 値、切り替えの月を定義する整数値、切り替えを行う週を定義する整数値、および切り替えを行う曜日を定義する DayOfWeek 値を渡します。 このメソッド呼び出しにより、TimeZoneInfo.TransitionTime オブジェクトがインスタンス化されます。

    2. タイム ゾーン調整の切り替え終了時刻を定義します。 これには、TimeZoneInfo.TransitionTime.CreateFloatingDateRule メソッドをもう一度呼び出す必要があります。 このメソッド呼び出しでは、2 番目の TimeZoneInfo.TransitionTime オブジェクトがインスタンス化されます。

    3. CreateAdjustmentRule メソッドを呼び出して、その調整が有効になる開始日と終了日、切り替えによって変動する時間数を定義する TimeSpan オブジェクト、および夏時間への切り替えと夏時間からの切り替えが行われる日時を定義する 2 つの TimeZoneInfo.TransitionTime オブジェクトを渡します。 このメソッド呼び出しにより、TimeZoneInfo.AdjustmentRule オブジェクトがインスタンス化されます。

    4. TimeZoneInfo.AdjustmentRule オブジェクトを、TimeZoneInfo.AdjustmentRule オブジェクトの配列に割り当てます。

  2. タイム ゾーンの表示名を指定します。 表示名は、世界協定時刻 (UTC: Coordinated Universal Time) からのタイム ゾーンのオフセットをかっこで囲み、その後にタイム ゾーン、タイム ゾーン内の 1 つ以上の都市、またはタイム ゾーン内の 1 つ以上の国や地域を表す文字列が続く標準形式に従います。

  3. タイム ゾーンの標準時間の名前を指定します。 通常は、この文字列がタイム ゾーンの ID としても使用されます。

  4. タイム ゾーンの夏時間の名前を指定します。

  5. タイム ゾーンの標準名とは異なる ID を使用する場合は、タイム ゾーン ID を指定します。

  6. UTC からのタイム ゾーンのオフセットを定義する TimeSpan オブジェクトをインスタンス化します。 UTC より後の時刻のタイム ゾーンでは正のオフセットになります。 UTC より前の時刻のタイム ゾーンでは負のオフセットになります。

  7. TimeZoneInfo.CreateCustomTimeZone(String, TimeSpan, String, String, String, TimeZoneInfo.AdjustmentRule[]) メソッドを呼び出して、新しいタイム ゾーンをインスタンス化します。

使用例

次の例では、1918 年から現在までのさまざまな期間に対する調整規則が含まれる、米国の中部標準時ゾーンを定義します。

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 がスローされます。

浮動調整規則の場合、特定の月の最終週に切り替えを行うことを示すには、CreateFloatingDateRule メソッドの week パラメーターに値 5 を渡します。

TimeZoneInfo.CreateCustomTimeZone(String, TimeSpan, String, String, String, TimeZoneInfo.AdjustmentRule[]) メソッドの呼び出しで使用する TimeZoneInfo.AdjustmentRule オブジェクトの配列を作成するときは、タイム ゾーンに対して作成する調整の数に合わせて配列のサイズを初期化してもかまいません。 このコード例では、代わりに、Add メソッドを呼び出して、各調整規則を TimeZoneInfo.AdjustmentRule オブジェクトのジェネリック List<T> コレクションに追加しています。 その後、CopyTo メソッドを呼び出して、このコレクションのメンバーを配列にコピーします。

この例では、CreateFixedDateRule メソッドを使用して、固定日付の調整も定義しています。 これは CreateFloatingDateRule メソッドの呼び出しと似ていますが、切り替えパラメーターの時刻、月、および日以外は必要とされない点が異なります。

この例は、次のようなコードを使用してテストできます。

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 への参照をプロジェクトに追加する。

  • 次の名前空間をインポートする。

    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    
表示: