2

我有一个 Windows文件时间:

一个 64 位值,表示自 1601 年 1 月 1 日 (UTC) 以来的 100 纳秒间隔数)

我需要将它向上舍入到最接近的偶数秒,如此所述。

我到目前为止的代码:

        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

3 回答 3

3

DateTime您可以更轻松地进行原始数学运算,而不是与对象斗争:

如果input是 100 纳秒的数量,则:

/10微秒数;
/10,000毫秒数;
/10,000,000秒数;
/20,000,000'两秒'的数量;

所以:

input = input / 20000000 * 20000000;

除法会将数字向下舍入到最后一个偶数秒,然后乘法将再次将其恢复为正确的大小。

但是你说你希望它向上取整:

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

在再次分解之前,这会在小数字上增加一“两秒”。

学究式地,如果恰好input在两秒标记处,那么这将增加两秒。要解决这个问题:

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

在决定增加它之前检查是否有任何分数“两秒”。至于您是否添加此额外检查,我将由您决定...

@Matthew Watson 指出,解决上述问题的通常程序员技巧是预先添加不足以翻转input到下一个“两秒”,然后继续进行除法然后乘法。如果input超过最小值,则将其翻转:

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

您的问题在于四舍五入到最近的第二行:

// 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 回答
0

使用原始刻度,然后将它们四舍五入到两秒的间隔。这比尝试在逗号后添加或删除内容更简单。

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 回答