在C#中安全地添加/减少日期到DateTime(Safely adding/subtracting days to DateTime in C#)

我有一个函数需要两个DateTime参数,我必须为这些日期添加单独的偏移量。 我知道DateTime有一个AddDays函数来为日期添加日期,如果DateTime小于MinValue或大于MaxValue ,则会引发异常。

现在我想要做一个安全的检查,是否在DateTime增加/减少以下天数可能导致流量过大或过低。

safeStartDate = (startDate == DateTime.MinValue || startDate == DateTime.MaxValue) ? startDate : startDate.AddDays(startDateOffset); safeEndDate = (endDate == DateTime.MaxValue || endDate == DateTime.MinValue) ? endDate : endDate.AddDays(enDateOffset);

通过这样做,我使它成为一个免费级别的异常,但日期可以是DateTime.Max - 1并在尝试添加偏移量时引发异常。 我正在寻找一种更好的方法,以确定最终值是否超过/低于实际计算流量,以防止异常。

I have a function which takes two DateTime parameters and I have to add separate offsets to these date. I know that DateTime has a AddDays function to add days to a date and it throws an exception if DateTime is less than MinValue or greater than MaxValue.

Now I want to do a safe check whether adding/subtracting the following number of days to a DateTime can cause over/under flow or not.

safeStartDate = (startDate == DateTime.MinValue || startDate == DateTime.MaxValue) ? startDate : startDate.AddDays(startDateOffset); safeEndDate = (endDate == DateTime.MaxValue || endDate == DateTime.MinValue) ? endDate : endDate.AddDays(enDateOffset);

By doing this, I am making it one level exception free but date can be DateTime.Max - 1 and while trying to add offset it throws an exception. I am looking a better way that whether the final values over/under flows without doing the actual calculation, in order to prevent exception.

最满意答案

如果不经常调用catch,你可以这样做:

try { safeDate = dt.AddDays(days); } catch (ArgumentOutOfRangeException) { safeDate = date; }

或者,

var maxDays = (DateTime.MaxValue - dt).TotalDays; safeDate = (days <= maxDays) ? dt.AddDays(days) : dt;

或者如果有负面的日子:

var maxDays = (DateTime.MaxValue - dt).TotalDays; var minDays = (DateTime.MinValue - dt).TotalDays; return (minDays <= days && days <= maxDays) ? dt.AddDays(days) : dt;

或者使用Rawling的答案 : CanAddDays(dt, days) ? dt.AddDays(days) : dt CanAddDays(dt, days) ? dt.AddDays(days) : dt

try / catch版本如果没有捕获,速度大约快25%,如果你这样做,速度大约慢1000倍。 因此,如果您希望在每5000次使用中捕获超过1次,则使用第二个版本。

If catch is not called very often you can do:

try { safeDate = dt.AddDays(days); } catch (ArgumentOutOfRangeException) { safeDate = date; }

Alternatively,

var maxDays = (DateTime.MaxValue - dt).TotalDays; safeDate = (days <= maxDays) ? dt.AddDays(days) : dt;

Or if there are negative days:

var maxDays = (DateTime.MaxValue - dt).TotalDays; var minDays = (DateTime.MinValue - dt).TotalDays; return (minDays <= days && days <= maxDays) ? dt.AddDays(days) : dt;

Or just use the method from Rawling's answer: CanAddDays(dt, days) ? dt.AddDays(days) : dt

The try/catch version is about 25% faster if you don't catch and about 1000x slower if you do. So, if you expected to catch more than about 1 time in every 5000 uses, then use the second version.

更多推荐