DateTime差异计算的OverflowException [重复]
Posted
技术标签:
【中文标题】DateTime差异计算的OverflowException [重复]【英文标题】:OverflowException on DateTime difference calculation [duplicate] 【发布时间】:2013-07-26 11:50:20 【问题描述】:我在这个小 sn-p 上遇到了一个奇怪的错误:
private int CalculateDifference(DateTime date1, DateTime date2)
var difference = date1 - date2;
return Math.Abs((int)difference.TotalSeconds);
就我而言,我计算的总秒数相差 3520789176.4909997。该程序抛出了一个我在十年的 C# 编码中从未见过的异常:
System.OverflowException: "Negating the minimum value of a twos complement number is invalid."
我很确定它与浮点运算有关,但我不了解细节,我只需要一个足够的解决方案来确定两个日期值的差异。
【问题讨论】:
阅读此***.com/questions/6265381/… 你很确定那是假的。 Int32.MaxValue 秒小于 70 年。 【参考方案1】:问题在于,当双精度值超出 int
可以表示的值范围时——即 -2,147,483,648 到 2,147,483,647,根据 C# 规范,结果是未定义的(参见 @987654323 @ 下面),但在 .NET 实现中,是 int.MinValue
。因此,当您将difference
转换为int
时,它会采用值-2,147,483,648,然后无法使用Math.Abs
来否定它
如果您将此方法转换为使用long
,它应该可以工作:
private long CalculateDifference(DateTime date1, DateTime date2)
var difference = date1 - date2;
return Math.Abs((long)difference.TotalSeconds);
您也可以通过在获取绝对值后简单地转换为int
来解决此问题:
private int CalculateDifference(DateTime date1, DateTime date2)
var difference = date1 - date2;
return (int)Math.Abs(difference.TotalSeconds);
【讨论】:
你:取最接近的值,-2,147,483,648 不,在这种特定情况下,它取最远的 价值。有可能(不完全确定)Int32.MinValue
在所有“不可能”的情况下都会产生。 C# 规范说:(下一条评论)
"在 unchecked
上下文中,转换总是成功的,并按如下进行。如果操作数的值为 NaN 或无穷大,则转换的结果是目标类型的未指定值. 否则,源操作数向零舍入到最接近的整数值。如果该整数值在目标类型的范围内,则该值是转换的结果。否则,转换的结果是未指定的值目标类型。”
另一种解决方案是difference.Duration().Ticks / TimeSpan.TicksPerSecond
(并且仍应返回long
)。看起来比较笨拙,但避免将整数转换为浮点数并再次转换回整数。
@JeppeStigNielsen 你是对的!我假设 OP 只是混淆了操作数的顺序,而 实际 值是 -3520789176.4909997
,但似乎如果该值是 >= 2147483648
或 -2147483648,结果将始终 @ 987654340@。 Double.NaN
、Double.PositiveInfinity
和 Double.NegativeInfinity
产生相同的结果。我会尽快更新我的答案。【参考方案2】:
根据msdn:Int.Maxvalue的值为2,147,483,647
你的数字似乎比那个更大。
【讨论】:
以上是关于DateTime差异计算的OverflowException [重复]的主要内容,如果未能解决你的问题,请参考以下文章
ELOQUENT - 在 where 子句中计算日期时间的差异