ToUniversalTime()。AddYears()。ToLocalTime()を呼び出すうるう年バグ?

StackOverflow https://stackoverflow.com/questions/603923

  •  03-07-2019
  •  | 
  •  

質問

.NETの DateTime 処理、具体的には ToLocalTime()の処理でうるう年に遭遇しました。問題を再現するコードをいくつか示します(私は太平洋時間帯にいます):

DateTime dtStartLocal = DateTime.Parse("2009-02-28T23:00:00.0-08:00");
DateTime dtEndLocal = dtStartLocal.AddYears(3);
DateTime dtStartUtc = dtStartLocal.ToUniversalTime();
DateTime dtEndUtc = dtStartUtc.AddYears(3);
DateTime dtEndLocal2 = dtEndUtc.ToLocalTime();
DateTime dtStartLocal2 = dtStartUtc.ToLocalTime();
Console.WriteLine("START: 1={0}, 2={0}", dtStartLocal, dtStartLocal2);
Console.WriteLine("END  : 1={0}, 2={1}", dtEndLocal, dtEndLocal2);
Console.ReadLine();

出力は次のとおりです。

  

START:1 = 2/28/2009 11:00:00 PM、2 = 2/28/2009 11:00:00 PM
  終了:1 = 2/28/2012 11:00:00 PM、2 = 2/29/2012 11:00:00 PM

ToUniversalTime()。AddYears(3).ToLocalTime()を実行した変数が AddYears(3)とは異なることに注意してください。1日先です。

これに遭遇した人はいますか?これが予想される場合、誰かがその背後にあるロジックを説明できますか?

注:はい、最善のアプローチはUTC間で完全に動作し、それらの間でフリップフロップを行わないことです。これは私に影響を与えるものではなく、私が遭遇した特異性です。基本的に、 AddYears()の仕組みを誤解していたので、なぜそれが実行されているのかがわかります(以下の選択した回答を参照)。

役に立ちましたか?

解決

これは正しく機能していると思います。

DateTime dtStartUtc = dtStartLocal.ToUniversalTime();

PSTはUTC-8です。したがって、これは時刻を2009年3月1日07:00:00に変換します。

DateTime dtEndUtc = dtStartUtc.AddYears(3);

これにより、前の時間に3年が追加され、2012年3月1日の07:00:00に置かれます。

DateTime dtEndLocal2 = dtEndUtc.ToLocalTime();

これにより、終了時刻がPSTに変換されます。PSTは2012年2月29日11:00:00です。

これは、ローカル時間とUTC時間の間の変換の副作用にすぎないと思います。

他のヒント

タイムゾーン/補正係数を印刷します。 .ToUniversialTime()を実行すると、基本的に元の時刻(「-08:00」)から8時間が加算され、2月28日の23:00時間から翌日の11:00に追加されます。したがって、3年を追加すると、29日の午前11:00になります。 2年をやっていたら、それは3月1日だったでしょう。うるう年とは関係ありません。

私が知る限り、この動作は間違っていません。現地時間をUTCに変換すると、事実上それを翌日にプッシュします。 3月1日3年を追加すると、3月1日のままになります。それを現地時間に変換し、前日にロールバックします。2012年はうるう年であるため、2月29日です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top