これは素晴らしい質問だと思います。(私はちょうどそれを発見しました。)
1900 年にかなり近い日付で操作していない限り、aDateTime
はOA 日付よりも精度が高くなります。しかし、いくつかのあいまいな理由で、DateTime
構造体の作成者は、 と他のものとの間で変換するときに、最も近い整数ミリ秒に切り捨てるのが大好きDateTime
です。言うまでもなく、これを行うと、正当な理由もなく多くの精度が失われます。
回避策は次のとおりです。
static readonly DateTime oaEpoch = new DateTime(1899, 12, 30);
public static DateTime FromOADatePrecise(double d)
{
if (!(d >= 0))
throw new ArgumentOutOfRangeException(); // NaN or negative d not supported
return oaEpoch + TimeSpan.FromTicks(Convert.ToInt64(d * TimeSpan.TicksPerDay));
}
public static double ToOADatePrecise(this DateTime dt)
{
if (dt < oaEpoch)
throw new ArgumentOutOfRangeException();
return Convert.ToDouble((dt - oaEpoch).Ticks) / TimeSpan.TicksPerDay;
}
さて、(あなたの質問から)DateTime
与えられたものを考えてみましょう:
var ourDT = new DateTime(634202170964319073);
// .ToSting("O") gives 2010-09-16T06:58:16.4319073
any の精度DateTime
は 0.1 µs です。
私たちが検討している日付と時刻の近くで、OA 日付の精度は次のとおりです。
Math.Pow(2.0, -37.0)
日、または約0.6286
マイクロ秒
この地域では、aDateTime
は OA の日付よりも (わずかに) 6 倍正確であると結論付けています。
上記の拡張メソッドを使用して変換ourDT
しましょうdouble
double ourOADate = ourDT.ToOADatePrecise();
// .ToString("G") gives 40437.2904679619
// .ToString("R") gives 40437.290467961888
ここで、上記の静的メソッドを使用して にourOADate
戻すと、次のようになります。DateTime
FromOADatePrecise
2010-09-16T06:58:16.4319072
(フォーマットで書かれてい"O"
ます)
オリジナルと比較すると、この場合の精度の損失は 0.1 µs であることがわかります。この間隔の長さは 0.8 µs であり、前述の 0.6286 µs に匹敵するため、精度の低下は ±0.4 µs 以内であると予想されます。
double
逆に、1900 年に近すぎない OA の日付を表すa から始めて、最初にを使用FromOADatePrecise
し、次に を使用すると、中間の精度がOA の精度よりも優れているため、ToOADatePrecise
に戻ります。この場合、完全な往復が期待されます。一方、BCL メソッドを同じ順序で使用すると、適切なラウンドトリップが得られる可能性は非常に低くなります (最初に使用したメソッドが非常に特殊な形式でない限り)。double
DateTime
FromOADate
ToOADate
double