2011-09-14 5 views
12

Doubleが文字列として書式設定されている場合、丸めが使用されます。例えば。DateTimeを文字列としてフォーマットし、ミリ秒に丸めないのはなぜですか?

Console.WriteLine(12345.6.ToString("F0")); 

出力

12346 

しかし、文字列の切り捨てを使用するようDateTimeがフォーマットされている場合。例えば。

var ci = CultureInfo.InvariantCulture; 
var dateTime = DateTime.Parse("2011-09-14T15:18:42.999", ci); 
Console.WriteLine(dateTime.ToString("o", ci)); 
Console.WriteLine(dateTime.ToString("s", ci)); 
Console.WriteLine(dateTime.ToString("yyyy-MM-hhThh:mm:ss.f", ci)); 

出力

2011-09-14T15:18:42.9990000 
2011-09-14T15:18:42 
2011-09-14T15:18:42.9 

この行動の背後にある理由(もしあれば)とは何ですか?最も近い秒に丸め


は、文字列として書式設定する前に半秒を添加することによって達成することができます。

var ci = CultureInfo.InvariantCulture; 
var dateTime = DateTime.Parse("2010-12-31T23:59:59.999", ci); 
Console.WriteLine(dateTime.ToString("s", ci)); 
var roundedDateTime = dateTime.AddMilliseconds(500); 
Console.WriteLine(roundedDateTime.ToString("s", ci)); 

出力

2010-12-31T23:59:59 
2011-01-01T00:00:00 

答えて

16

これは少し主観的であるが、私は言うだろうそれらを切り捨てるのではなく、丸めた日付と時刻の値が予期せぬ「より多くの」動作を引き起こす可能性があります。

例えば、new DateTime(2011, 1, 1, 23, 59, 59, 999)を四捨五入すると、完全に新しい日になります。これは値を切り捨てるよりもずっと奇妙に聞こえる。

+2

+1、ありがとうございます。それは私が決して考えなかった次元です。 –

+1

そして、新しい日が翌年になると、丸めは年まで一貫してカスケードします。ほとんどの状況では、おそらくあなたが望むものではないでしょう。 –

+1

多分それについて考えてみる別の方法:時間の単位は時間ではなく_スピンです。時間単位は、次の(同じ)ユニットの開始まで完全に延びます。たとえば、火曜日までの道のりの0.99999は、「水曜日」ではなく「火曜日」と考えられます。 – Spike0xff

0

最終測定単位で、その周波数でイベントが発生すると、エイリアシングが丸められます。

たとえば、1秒のデータフレームを2mSにして2番目のフレームに入れ、次のフレームを990mSにすると、同じ秒になるようにスタンプされます。わずか数ミリ秒のジッタは、散在している一意でないキー値を多く生じることになります。

ジッタがはるかに厳しくなるまで、反復すると数秒になるでしょう。 +/- 499 mSです。

丸めの目的は、解決を永遠に止めることです。 不確かさが分解能を下回ると、エイリアシングが大幅に削減されます。

「カスケード」は、境界の解像度よりも小さい場合にのみ発生します。 たとえば、トグルしている年の数字は衝撃的ですが、これは新年の真夜中の1秒(またはミリ秒など)よりも少なくても でしか発生しません。予期しないものはありません またはそれは特に不正確です。

実際にエイリアシングを防止するには(同じ時間を2回繰り返す)、丸めた後に のアンチエイリアス(グラフィックスと同じように)を実装する必要があります。

1

古い質問ですが、新しい質問から言及されていますが、回答は四捨五入の理由について議論されています(もちろん有効です)。

丸めを行わない理由は、ToStringは、あなたが求めている日時の部分を印刷するだけです。

したがって、例えば、それは最も近い分に丸めますどちら:

Console.WriteLine(dateTime.ToString("yyyy-MM-hhThh:mm", ci)); 

出力:

2011-09-03T03:18 

パラメータなしで、ToStringは、お使いの環境のデフォルトの日付/時刻形式の文字列を使用しています。

関連する問題