以C#表示的舍入文件时间,以适应FAT舍入

以C#表示的舍入文件时间,以适应FAT舍入,c#,datetime,math,filetime,C#,Datetime,Math,Filetime,我有一个窗户: 表示100纳秒间隔数的64位值 自1601年1月1日起(UTC)) 我需要把它四舍五入到最接近的偶数秒,如前所述 到目前为止,我掌握的代码是: var originalDt = DateTime.FromFileTimeUtc(input); // round it UP to the nearest Second var newDt = originalDt.AddMilliseconds(1000 - originalDt.M

我有一个窗户:

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

我需要把它四舍五入到最接近的偶数秒,如前所述

到目前为止,我掌握的代码是:

        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,我的目标是13079024780000000


数学不是我最擅长的科目。。。我能安全地把最后四位数归零吗?或者我应该忘记上面的代码,把最后八位完全归零吗?或另一种方法?

与使用
DateTime
对象相比,您可以更轻松地进行原始数学运算:

如果
input
为100纳秒,则:

/10
表示微秒数
/10000
表示毫秒数
/10000000
表示秒数
/20000000
表示“两秒”的数字

因此:

除法将数字四舍五入到最后一个偶数秒,然后乘法将使其再次回到正确的大小

但你说你想把它凑起来:

input = (input / 20000000 + 1) * 20000000;
在再次分解之前,这会给这个小数字加上一个“两秒钟”

学究般地说,如果
输入
正好处于两秒标记,那么这将增加两秒。要解决这个问题:

if (input % 20000000!=0) {
    input = (input / 20000000 + 1) * 20000000;
} // if
这会检查是否存在任何分数“两秒”,然后再决定将其放大。我会让你决定是否加这张额外的支票

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

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

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

const long twoSecondsInTicks = 20000000;    // 20 million
long twoSecondIntervals = originalDt.Ticks / twoSecondsInTicks;
if (originalDt.Ticks % twoSecondsInTicks != 0) ++twoSecondIntervals;
var newDt = new DateTime(twoSecondIntervals * twoSecondsInTicks);
您的问题是在四舍五入到最近的第二行:

保留毫秒的完整分数(因为
originalDt.millis秒
是一个整数值)、微秒和纳秒;应该是

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

当使用最小的日期时间单位ticks时,您将获得预期的
130790247820000000
,而不需要纳秒(
…8763

也正是我想要的。实际上,我认为您可以做
输入=((输入+20000000-1)/20000000)*20000000以避免进行模数运算calculation@Matthew是的!现在向一个自认的非同性恋者解释一下-mathematician@JohnBurger谢谢,这正是我想要的答案!用
value=N*(value/N+N-1)
// round it UP to the nearest Second
var newDt = originalDt.AddMilliseconds(1000 - originalDt.Millisecond);
// round it UP to the nearest Second
var newDt = originalDt.AddTicks( - (originalDt.Ticks % TimeSpan.TicksPerSecond));