2009-04-20 7 views
2

DateTime.AddDays()にはdoubleというパラメータがあるため、日を追加すると丸め誤差が発生する可能性があります。たとえば、次のループがあるとしましょう:DateTime.AddDaysはどのくらい正確ですか?

DateTime Now = DateTime.Today; 
for (int i = 0; i < 365; ++i) 
{ 
    Now = Now.AddDays(1); 
    // do something 
} 

私は今や真夜中から漂流するかもしれないと心配しています。私はいつも少し遅くなることがあり、このような何かをしたくなるが、私の妄想を軽減しています:

for (int i = 0; i < 365; ++i) 
{ 
    Now = Now.AddDays(1.01).Date; 
    // do something 
} 
+0

あなたは今、23 = 'を使用して提案された方法を呼び出す場合:59'を、それが間違っになります結果。 – mafu

答えて

11

DateTimeは、1ティックが100ナノ秒を表す64ビット整数として内部日付を格納します。エラーは発生しません。ある日は864,000,000,000ダニで、Doubleは最低15桁の精度です。したがって、が1日であれば、Doubleは1ティックより高い解像度を持つので、ダンプに丸めるとすべてのエラーは消えます。

の場合、が1年に等しい場合、Doubleは1ティックを表すのに十分な精度がないため、これは当てはまりません。しかし、DateTimeクラスを見れば、そのデザインはその事実(AddMonths()AddYears())が浮動小数点数の引数でもなく整数でもあることが分かります。

これを確認するには、次のコードを実行してください。

DateTime now = DateTime.Now; 

// Displays 864000000000 
Console.WriteLine(now.AddDays(1.0).Ticks - now.Ticks); 
0

あなたが離れ深夜から漂流とはどういう意味ですか?

実行すると、最初のコードの最終日は2010年4月20日の12:00:00です。
私はそれがあなたが期待していると思います。ではない?

0

例のように、DateTime変数に1日を100,000回追加し、深夜の値の日付で終了しました。心配する理由はないようです。

私は彼らがタイムティックに丸めていると確信しています。ドリフトに関する問題はなくなります。

1

日数は整数(スケール)を乗じ、次いでDateTimeにより記憶されたティック数に加算されます。整数を渡すと、整数の目盛りが追加されます。

一方、.NETがうるう秒についてどういうことをしているのかわかりません...私はそれがあなたのコードを大丈夫なまま残している、とてもシンプルなモデルを使用していると思われます。

タイムゾーンを追加すると複雑な問題が発生することを忘れないでください.1日をローカルに追加すると、1日以上のUTCが追加されることがあります。

+0

+1うるう秒Jon;) –

2

一般に、すべての実数が2倍で絶対に表現できるわけではないので、ダブルスで四捨五入することを心配するのは間違いないと思います。たとえば、1日の1/3を3回追加すると、正確に1日の前進で終わることはありません。しかし、この場合、1は絶対的に表現可能な数値であり、単純に2倍(1日のティック数)で表現可能な別の数で単純に乗算しているので、大丈夫です。 2番目のサンプルはおそらく過剰です。

例:(2009年4月20日に)で

DateTime now = DateTime.Today; 
for (int i = 0; i < 7; ++i) 
{ 
    for (int j = 0; j < 7; ++j) 
    { 
     now = now.AddDays(1/7.0); 
    } 
} 
Console.WriteLine(DateTime.Today); 
Console.WriteLine(now); 

結果

4/20/2009 12:00:00 AM 
4/26/2009 11:59:59 PM 
+0

あなたの例にメモを付けるべきでしょうか。 Doubleが正確に1を返すことができるという事実は、これがすべての整数にとって当然間違っているという結論につながる可能性があります。 –

+0

これが問題になるには、非常に長い日数を追加する必要があります。二重に少なくとも15桁の有効数字があるので、あなたは日付の時間構造を最初にオーバーフローさせると思う。 – tvanfosson

関連する問題