System.InvalidTimeZoneException
タイム ゾーン情報が無効である場合にスローされる例外。
いくつかの発生パターンがあるようだが、今回はそのうちの2つを確認。
[実験ソース(C#)]
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// 10月の第2日曜日の4時に開始
TimeZoneInfo.TransitionTime s = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(
new DateTime(1, 1, 1, 4, 0, 0), 10, 2, DayOfWeek.Sunday);
// 3月の第2日曜日の3時に終了
TimeZoneInfo.TransitionTime e = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(
new DateTime(1, 1, 1, 3, 0, 0), 3, 2, DayOfWeek.Sunday);
// 1時間ずれる
TimeSpan delta = new TimeSpan(1, 0, 0);
// 2000年以降、s〜e の期間、1時間の夏時間を持つルールを作成
TimeZoneInfo.AdjustmentRule a = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(
new DateTime(2000, 1, 1), DateTime.MaxValue.Date, delta, s, e);
TimeSpan offset = new TimeSpan(+14, 0, 0); // 夏時間の+1 とあわせて計14を超える
TimeZoneInfo.AdjustmentRule[] r = { a };
TimeZoneInfo.CreateCustomTimeZone("tzId", offset, "dispName", "stdName", "daylight", r);
}
}
}
[結果]
ハンドルされていない例外: System.InvalidTimeZoneException: BaseUtcOffset プロパティと DaylightDelta プロパティの合計はプラス マイナス 14.0 時間の範囲内である必要があります。
場所 System.TimeZoneInfo.ValidateTimeZoneInfo(String id, TimeSpan baseUtcOffset, AdjustmentRule[] adjustmentRules, Boolean& adjustmentRulesSupportDst)
場所 System.TimeZoneInfo..ctor(String id, TimeSpan baseUtcOffset, String displayName, String standardDisplayName, String daylightDisplayName, AdjustmentRule[] adjustmentRules, Boolean disableDaylightSavingTime)
場所 ConsoleApplication1.Program.Main(String[] args) 場所 Program.cs:行 22
[対処など]
世界協定時刻 (UTC: Coordinated Universal Time) オフセットと夏時間のデルタの合計が、±14時間の範囲内にないとこのエラーとなる。たとえば日本の場合、日本標準時(JST)は、+9時間なので、20行目の TimeSpan offset を +9に変えてやることで例外は発生しない。
もう1つ、複数ルール指定した場合のケースを実験してみる。
[実験ソース(C#)]
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// 10月の第2日曜日の4時に開始
TimeZoneInfo.TransitionTime s = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(
new DateTime(1, 1, 1, 4, 0, 0), 10, 2, DayOfWeek.Sunday);
// 3月の第2日曜日の3時に終了
TimeZoneInfo.TransitionTime e = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(
new DateTime(1, 1, 1, 3, 0, 0), 3, 2, DayOfWeek.Sunday);
// 1時間ずれる
TimeSpan delta = new TimeSpan(1, 0, 0);
// 2000年以降、s〜e の期間、1時間の夏時間を持つルールを作成
TimeZoneInfo.AdjustmentRule a = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(
new DateTime(2000, 1, 1), DateTime.MaxValue.Date, delta, s, e);
// 2010年〜2020年の夏時間ルールを作成
TimeZoneInfo.AdjustmentRule b = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(
new DateTime(2010, 1, 1), new DateTime(2020, 12, 31), delta, s, e);
TimeSpan offset = new TimeSpan(+9, 0, 0);
TimeZoneInfo.AdjustmentRule[] r = { a, b };
TimeZoneInfo.CreateCustomTimeZone("tzId", offset, "dispName", "stdName", "daylight", r);
}
}
}
[結果]
ハンドルされていない例外: System.InvalidTimeZoneException: AdjustmentRule 配列の要素は時系列である必要があり、重複することはできません。
場所 System.TimeZoneInfo.ValidateTimeZoneInfo(String id, TimeSpan baseUtcOffset, AdjustmentRule[] adjustmentRules, Boolean& adjustmentRulesSupportDst)
場所 System.TimeZoneInfo..ctor(String id, TimeSpan baseUtcOffset, String displayName, String standardDisplayName, String daylightDisplayName, AdjustmentRule[] adjustmentRules, Boolean disableDaylightSavingTime)
場所 ConsoleApplication1.Program.Main(String[] args) 場所 Program.cs:行 26
[対処など]
複数ルールを指定する場合は、期間が重複しないようにする。上記の例では、1つ目のルール(a)が2000年以降無限に適用される期間設定になっていることが原因。