1

ASP.NET で正確なタイムゾーンを使用するために、 http: //www.babiej.demon.nl/Tz4Net/main.htm の TZ4Net ライブラリ を使用しています。

最近、「移行期間中のソース時間」が表示されるようになりました。

コードのこの部分から

static DateTime Convert(DateTime srcTime, string srcName, string dstName)
{
  if (OlsonTimeZone.LookupName(srcName) == null)
{
  throw new ArgumentException("Unknown source timezone name.");
}
if (OlsonTimeZone.LookupName(dstName) == null)
{
  throw new ArgumentException("Unknown destintation timezone name.");
}
OlsonTimeZone srcZone = OlsonTimeZone.GetInstance(srcName);
TimeCheckResult srcCheckRes = srcZone.CheckLocalTime(srcTime);
switch (srcCheckRes)
{
case TimeCheckResult.Valid :
{
  OlsonTimeZone dstZone = OlsonTimeZone.GetInstance(dstName);
  DateTime dstTime = dstZone.ToLocalTime(srcZone.ToUniversalTime(srcTime));
  return dstTime;
}
case TimeCheckResult.InSpringForwardGap :
case TimeCheckResult.InFallBackRange :
{
  throw new ArgumentException("Source time in transition period."); // THIS PART HERE
}
default :
{
  throw new ArgumentException("Source time out of range.");
}
}
}

TimeCheckResult.InFallBackRange とは何ですか? このタイプのエラーを処理するにはどうすればよいですか?

4

3 に答える 3

1

「スプリング フォワード」および「フォール バック」という用語は、夏時間の変更を指します。詳細については、DST タグ wikiを参照してください。

「Spring Forward」移行中に、現地時間に存在しないギャップ値があります。たとえば、米国では、ほとんどのタイム ゾーンが 3 月の第 2 日曜日の 1:59:59 から 3:00:00 にスキップします。したがって、2:00:00 の時間はギャップにあるため無効です。

「フォールバック」移行中、現地時間に2 回存在する値の範囲があります。たとえば、米国では、ほとんどのタイム ゾーンが 11 月の第 1 日曜日の 1:59:59 から 1:00:00 に戻ります。したがって、1:00:00 の時間は2 回存在するため、2 つの瞬間のどちらを参照できるかはあいまいです。

移行期間に該当する現地時間から変換しようとしている場合は、次のことを行う必要があります。

  • 「Spring Forward」移行によって作成されたギャップに陥る時間については、実際にはまったく有効な時間ではありません。

    • ユーザーが有効な時間を入力できるように、ユーザーにエラー メッセージを表示する必要があります。

    • または、DST の調整を忘れただけであると想定したい場合は、節約分 (通常は 1 時間) だけ時間を進めることができます。これは、毎日繰り返されるイベントによく使用されます。

  • 「フォールバック」遷移に該当するためあいまいな時間については、2 つの可能性のどちらを実際に使用するかを決定する必要があります。

    • 多くの場合、ユーザーが決定できるように、2 つの選択肢を提示する必要があります。「EDT 1:00 (-0400) または EST 1:00 (-0500) のことですか?」という質問をします。

    • 時々、あなたはそれらを選びたいと思うでしょう。要件に応じて、最初のオカレンスまたは 2 番目のオカレンスを選択できます。

TZ4Net は優れたライブラリであり、作者 (Zbigniew Babiej) は親切にも何年にもわたってそれを保守してくれました。ただし、もともとは .NET 2.0 の頃に作成されたものであるため、DateTimeOffset値を処理しません。また、使用される値の.Kindプロパティも考慮しません。DateTime.Net 2.0 で導入されましたが、これがTZ4NetDateTimeKindに組み込まれたことはないようです。そのため、関数に正しい値を与えるように十分注意する必要があります。

Olson タイム ゾーンを引き続き使用する場合は、TZ4Net を使用できますが、Noda Timeを試すこともお勧めします。これは (単独の作者ではなく) コミュニティが開発したオープン ソース プロジェクトであり、主任開発者はJon Skeetです。DST の移行に関しても同じ懸念がありますが、Noda Time の API を使用すると、アプリケーションの展開後にこれらの問題を確認するのではなく、事前にこれらの問題に対処する必要があります。

現在持っているものを保持したい場合は、上記の関数を次のように変更して、フォールバック遷移を処理できます。

  • 最初の (昼光) インスタンスを想定するには:

    case TimeCheckResult.InFallBackRange:
    {
        OlsonTimeZone dstZone = OlsonTimeZone.GetInstance(dstName);
        DateTime dstTime = dstZone.ToLocalTime(srcZone.ToUniversalTime(srcTime.AddHours(-1)).AddHours(1));
        return dstTime;
    }
    
  • 2 番目の (標準) インスタンスを想定するには:

    case TimeCheckResult.InFallBackRange:
    {
        OlsonTimeZone dstZone = OlsonTimeZone.GetInstance(dstName);
        DateTime dstTime = dstZone.ToLocalTime(srcZone.ToUniversalTime(srcTime.AddHours(1)).AddHours(-1));
        return dstTime;
    }
    

Spring Forward トランジションの場合:

  • おそらくこれを保持する必要があります:

    case TimeCheckResult.InSpringForwardGap:
        throw new ArgumentException("Source time in transition period.");
    
  • しかし、ユーザーがクロックを進めるのを忘れただけだと仮定したい場合は、これを実行して変換で進めることができます。

    case TimeCheckResult.InSpringForwardGap:
    {
        OlsonTimeZone dstZone = OlsonTimeZone.GetInstance(dstName);
        DateTime dstTime = dstZone.ToLocalTime(srcZone.ToUniversalTime(srcTime.AddHours(1)));
        return dstTime;
    }
    
于 2013-10-30T22:02:42.827 に答える
0

TZ4NET の作成者からの応答

こんにちはマシュー、

これは、2013 年 11 月 3 日 1:26:00 がソース タイムゾーンであいまいな時刻であることを意味します。たとえば、2013 年 11 月 3 日の 02:00 の America/New_York では、時刻が 01:00 に戻されます。これは、時刻 01:26 がその日に 2 回発生することを意味するため、変換中に、最初の発生を参照するか、2 番目の発生を参照するかが明確ではありません。これらは異なる UTC 時間に対応するためです。これを検出し、ユーザーが正確に何を参照しているかを詳しく説明するように依頼するのが最善だと思います。これがインタラクティブなプロセスでない場合、最も簡単な方法は、それを検出し、ソース時間に 1 時間を追加してから、目的時間から 1 時間を減算することです。

これがあなたの質問に答えてくれることを願っています, よろしく, ZB

于 2013-11-01T12:39:36.627 に答える