将TimeSpan.TotalMilliseconds转换为long

时间:2011-04-10 13:11:46

标签: c# .net timespan

我有一些DateTime变量,我想使用System.Threading.Timer等到这个时间到来。如果时间过去,我希望计时器立即打勾。

问题 TimeSpan.TotalMillisecondsdouble,而计时器到期时间最大类型为long

我尝试使用以下代码将截止时间延长到long.MaxValue

DateTime someUtcTime;
// Max due time to long.MaxValue
double doubleDueTime = Math.Min(
    (double)long.MaxValue,
    someUtcTime.Subtract(DateTime.UtcNow).TotalMilliseconds);

// Avoid negative numbers
long dueTime = Math.Max(0L, (long)doubleDueTime);

_timer.Change(dueTime, System.Threading.Timeout.Infinite);

但事实证明施放long.MaxValue加倍并返回长结果为负数(在未经检查的诅咒代码中)。请发给我代码。


编辑:显然,无论您使用哪个Timer.Change重载,它们都限制在4294967294(UInt32.MaxValue - 1)毫秒。


解决方案:

涵盖两种极端情况(someUtcTime = DateTime.MaxValue; UtcNow = DateTime.MinValue;,反之亦然)。

const uint MAX_SUPPORTED_TIMEOUT = uint.MaxValue - 1; //0xfffffffe

DateTime someUtcTime;
double doubleDueTime = (someUtcTime - DateTime.UtcNow).TotalMilliseconds;

// Avoid negative numbers
doubleDueTime = Math.Max(0d, doubleDueTime);

// Max due time to uint.MaxValue - 1
uint dueTime = (uint)Math.Min(MAX_SUPPORTED_TIMEOUT, doubleDueTime);

4 个答案:

答案 0 :(得分:3)

也许只使用Ticks属性(Ticks为Long)并乘以TimeSpan.TicksPerMillisecond(常量,每毫秒10,000个滴答)。

答案 1 :(得分:2)

由于(DateTime.MaxValue - DateTime.MinValue).TotalMilliseconds为315537897600000且long.MaxValue为9223372036854775807(long可以表示比任意两个DateTime值之间的最大可能毫秒数大4个数量级的值),你永远不会将来有太多时间。

这就足够了:

DateTime someUtcTime;
// Max due time to long.MaxValue
double doubleDueTime = (someUtcTime - DateTime.UtcNow).TotalMilliseconds;

// Avoid negative numbers
long dueTime = Math.Max(0L, (long)doubleDueTime);

_timer.Change(dueTime, System.Threading.Timeout.Infinite);

答案 2 :(得分:2)

Timespan timespan = someUtcTime.Subtract(DateTime.UtcNow);
long time = timespan.TotalMilliseconds <= long.MaxValue ? (long)timespan.TotalMilliseconds : -1;

if (time == -1) {
 sorry.nocando();
}
else {
 just.doit();
}
顺便说一下:在很长一毫秒的时间里你可以有292471208的时间跨度,我认为你的代码不会被使用。太阳已经有可能已经扩展过火星,地球已经不复存在了:D

答案 3 :(得分:0)

定时器旨在等待间隔(通常短于24小时)。

您的预期用途是什么?调度程序通常会有一个事件/任务列表,并定期每分钟(可能每秒)检查一次是否需要触发任何任务。

或许像Quartz.Net这样的东西可能合适吗?