2

私は Windows FILETIMEを持っています:

1601 年 1 月 1 日 (UTC) からの 100 ナノ秒間隔の数を表す 64 ビット値)

here で説明されているように、最も近い偶数秒に切り上げる必要があります。

私がこれまでに持っているコード:

        var originalDt = DateTime.FromFileTimeUtc(input);

        // round it UP to the nearest Second
        var newDt = originalDt.AddMilliseconds(1000 - originalDt.Millisecond);

        // then if our new Second isn't even
        if (newDt.Second % 2 != 0)
        {
            // add one second to it, then it'll be even
            newDt = newDt.AddSeconds(1);
        }

        return newDt.ToFileTimeUtc();

うまくいきません... 130790247821478763 が 130790247820008763 に変わります。130790247800000000 の後です。

数学は私の得意科目ではありません... 下 4 桁を安全にゼロにすることはできますか? または、上記のコードを忘れて、最後の 8 桁を完全にゼロにする必要がありますか? それとも... 別の方法ですか?

4

3 に答える 3

3

オブジェクトに苦労するよりもDateTime、生の数学を行う方が簡単かもしれません。

inputが 100 ナノ秒の場合、次のようになります。

/10マイクロ秒数。
/10,000ミリ秒数。
/10,000,000秒数;
/20,000,000「2 秒」の数。

そう:

input = input / 20000000 * 20000000;

除算により数値が最後の偶数秒に切り捨てられ、乗算により再び正しいサイズに戻されます。

しかし、あなたはそれを切り上げたいと言った:

input = (input / 20000000 + 1) * 20000000;

これは、再び因数分解する前に、小さい数に 1 '2 秒' を追加します。

厳密に言えばinput正確に 2 秒のマークにあった場合、これにより 2 秒が追加されます。それを修正するには:

if (input % 20000000!=0) {
    input = (input / 20000000 + 1) * 20000000;
} // if

これは、「2 秒」の端数があるかどうかを確認してから、それを増やすことを決定します。この追加のチェックを追加するかどうかは、あなたにお任せします...

@Matthew Watsonは、上記の問題に対する通常のプログラマーのトリックは、次の「2秒」にロールオーバーするのに十分ではない事前追加を行ってから、除算してから乗算することであると指摘しています。input最小値を超えていた場合inputは、ロールオーバーします。

    const long twoSeconds = 20000000;
    ...
    input = (input + twoSeconds - 1) / twoSeconds * twoSeconds;
于 2016-06-15T14:14:25.540 に答える
0

生の目盛りを使用してから、これらを 2 秒間隔に丸めます。これは、コンマの後に何かを追加または削除しようとするよりも簡単です。

const long twoSecondsInTicks = 20000000;    // 20 million
long twoSecondIntervals = originalDt.Ticks / twoSecondsInTicks;
if (originalDt.Ticks % twoSecondsInTicks != 0) ++twoSecondIntervals;
var newDt = new DateTime(twoSecondIntervals * twoSecondsInTicks);
于 2016-06-15T14:16:08.597 に答える
0

あなたの問題は、最も近い2行目に切り上げることにあります:

// round it UP to the nearest Second
var newDt = originalDt.AddMilliseconds(1000 - originalDt.Millisecond);

ミリ秒(は整数値であるため)、マイクロ- およびナノ- 秒の分数をそのまま残します。そのはずoriginalDt.Millisecond

// round it UP to the nearest Second
var newDt = originalDt.AddTicks( - (originalDt.Ticks % TimeSpan.TicksPerSecond));

可能な限り最小の日時単位であるticksを使用する場合、ナノ秒なしで期待されます( )130790247820000000...8763

于 2016-06-15T14:41:16.147 に答える