在C#中舍入FILETIME以适应FAT舍入

时间:2016-06-15 14:00:03

标签: c# datetime math filetime

我有一个Windows FILETIME

  

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

我需要将它向上舍入到最接近的偶数秒,如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。

数学不是我最强的主题......我可以安全地将最后四位数归零吗?或者我应该忘记上面的代码并完全归零后八位数?或者......另一种方式?

3 个答案:

答案 0 :(得分:3)

你可能更容易做原始数学,而不是与DateTime对象挣扎:

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

/10表示微秒数;
/10,000表示毫秒数;
/10,000,000秒数;
/20,000,000代表'两秒钟的数量&#39 ;;

所以:

input = input / 20000000 * 20000000;

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

但是你说你希望它四舍五入:

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

这增加了一个“两秒钟”'在重新考虑它之前的小数字。

迂腐地说,如果input处于完全两秒标记,那么这会增加两秒钟。解决这个问题:

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

检查是否存在任何小数' 2秒'在决定提高它之前。我会告诉您是否添加了额外的支票......

@Matthew Watson指出,通常的程序员对上述问题的伎俩是预先添加不够足以将input推到下一个'两秒钟& #39;然后继续进行除 - 然后乘法。如果input超过最低限度,则会将其翻过来:

    const long twoSeconds = 20000000;
    ...
    input = (input + twoSeconds - 1) / twoSeconds * twoSeconds;

答案 1 :(得分:0)

使用原始刻度线,然后将它们围绕两秒钟进行舍入。这比在逗号后添加或删除内容更简单。

const long twoSecondsInTicks = 20000000;    // 20 million
long twoSecondIntervals = originalDt.Ticks / twoSecondsInTicks;
if (originalDt.Ticks % twoSecondsInTicks != 0) ++twoSecondIntervals;
var newDt = new DateTime(twoSecondIntervals * twoSecondsInTicks);

答案 2 :(得分:0)

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

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

你保留完整的分数毫秒(因为originalDt.Millisecond整数值), micro - 和 nano - 秒;它应该是

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

使用 ticks 最小可能的日期时间单位时,您将得到130790247820000000而不用纳秒({{ 1}})