检查添加TimeSpans是否超过TimeSpan.MaxValue

3

我正在尝试将一些时间段加在一起进行计算。
例如:

var timeSpan1 = new TimeSpan.FromMinutes(1);
var timeSpan2 = new TimeSpan.MaxValue; 
var timeSpan3 = timeSpan1 + timeSpan2;

在这种情况下,时间跨度将超过TimeSpan.MaxValue并抛出异常。
System.OverflowException:时间跨度溢出,因为持续时间太长。
添加TimeSpans的正确方法是什么?
我是否需要在其周围放置try-catch或编写自己的扩展方法?看起来这应该是.NET框架的一部分 - 要么默认为MaxValue,要么有一个TryAdd方法。

你为什么认为抛出异常不是正确的行为?考虑一下,如果 timeSpan3 的结果是 TimeSpan.MaxValue,那么你将违反数学规则,使得 timeSpan3 - timeSpan1 != timeSpan2 - Matt Johnson-Pint
@MattJohnson 很好的观点!然而,我对MaxValue的使用情况是将其作为“无穷大”。因此,无穷大 + 无穷大 = 无穷大。在这种情况下,我也不应该使用无穷大 - 时间跨度 = ...并依赖于结果。 - JumpingJezza
2个回答

4

我会使用代数,并保持所有内容在 TimeSpan 单位中:

public static TimeSpan AddTimeSpan(this TimeSpan ts1, TimeSpan ts2)
{
    bool sign1 = ts1 < TimeSpan.Zero, sign2 = ts2 < TimeSpan.Zero;

    if (sign1 && sign2)
    {
        if (TimeSpan.MinValue - ts1 > ts2)
        {
            return TimeSpan.MinValue;
        }
    }
    else if (!sign1 && !sign2)
    {
        if (TimeSpan.MaxValue - ts1 < ts2)
        {
            return TimeSpan.MaxValue;
        }
    }

    return ts1 + ts2;
}

这样,您就可以利用 TimeSpan 而不需要将其转换为其他单位,并且您可以确保在添加过程中不会出现其他可能出现的问题(我认为可以安全地假设 TimeSpan 范围不会改变,以致于 TotalMinutes 不再适用,但是当您接近 TimeSpan.MinValueTimeSpan.MaxValue 的极限时,您可能会遇到一些精确加法结果方面的不准确性)。


我最终又改回使用ticks了。调用这个方法三四百万次比较TimeSpans的性能损失太大了。 - JumpingJezza

0

我最后写了一个TimeSpan的扩展方法。还需要检查TimeSpan.MinValue,因为可以添加负数。一开始我是通过检查Ticks来判断TimeSpans,但是结果有些奇怪。显然TimeSpan.MinValue.Ticks + TimeSpan.MinValue.Ticks = 2?

所以改成:

public static TimeSpan AddTimeSpan(this TimeSpan firstTimeSpan, TimeSpan secondTimeSpan)
{
    if (firstTimeSpan.TotalMinutes + secondTimeSpan.TotalMinutes > TimeSpan.MaxValue.TotalMinutes)
    {
        return TimeSpan.MaxValue;
    }
    if (firstTimeSpan.TotalMinutes + secondTimeSpan.TotalMinutes < TimeSpan.MinValue.TotalMinutes)
    {
        return TimeSpan.MinValue;
    }
    return firstTimeSpan + secondTimeSpan;
}

1
看起来在比较Ticks的符号位。可以参考以下引用源代码:https://referencesource.microsoft.com/#mscorlib/system/timespan.cs,574ccdd4f806977f - Slai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接