我有一个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。
数学不是我最强的主题......我可以安全地将最后四位数归零吗?或者我应该忘记上面的代码并完全归零后八位数?或者......另一种方式?
答案 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}})