将秒添加到具有有效双精度的DateTime会导致ArgumentOutOfRangeException
本文关键字:DateTime ArgumentOutOfRangeException 双精度 有效 添加 | 更新日期: 2023-09-27 18:29:13
以下代码崩溃和烧录,我不明白为什么:
DateTime dt = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);
double d = double.Parse("1332958778172");
Console.Write(dt.AddSeconds(d));
有人能告诉我发生了什么事吗?我似乎不明白为什么。。。
编辑
这个值来自Salesforce REST API和我所理解的Unix epoch时间戳"令牌发布时间,表示为自Unix epoch(1970年1月1日00:00:00 UTC)以来的秒数。"
解决方案
Salesforce REST API实际上在执行OAuth请求时为issued_at
字段发回毫秒,而他们说他们正在发送秒。。。
正如其他人所说,问题在于值太大。
仔细看了一下,我相信它代表了自Unix时代以来的毫秒,而不是秒所以你想要:
DateTime dt = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);
double d = double.Parse("1332958778172"); // Or avoid parsing if possible :)
Console.Write(dt.AddMilliseconds(d));
要么这样,要么在调用AddSeconds
之前除以1000——但显然这会丢失数据。
您添加的值导致日期超出DateTime支持的有效日期范围。
DateTime支持01/01/0001 00:00:00至31/12/9999 23:59:59。
1332958778172/3600/24/365的简单计算得出42267年。
我认为double值确实太大了。它代表了42267年多一点(如果我的数学计算正确的话),DateTime.MaxValue是23:59:59.999999999999年12月31日
DateTime dt = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);
Console.Write(dt.AddSeconds(1332958778172D));
除了。。。
1332958778172/60/60/24/365=42267年。。。日期时间只能截止到23:59:59.999999999999年12月31日
我遇到了类似的问题,需要在日期时间中添加一个可配置的时间跨度。如果配置不正确,我必须假设"最坏的情况":MaxValue。
我通过实现DateTime的扩展(仍处于测试阶段)解决了这个问题:
/// <summary>
/// Removes a timespan from a date, returning MinValue or MaxValue instead of throwing exception when if the resulting date
/// is behind the Min/Max values
/// </summary>
/// <returns></returns>
public static DateTime SafeAdd(this DateTime source, TimeSpan value)
{
// Add or remove ?
if (value.Ticks > 0)
{
// add
var maxTicksToAdd = DateTime.MaxValue - source;
if (value.Ticks > maxTicksToAdd.Ticks)
return DateTime.MaxValue;
}
else
{
var maxTicksToRemove = source - DateTime.MinValue;
// get the value to remove in unsigned representation.
// negating MinValues is impossible because it would result in a value bigger than MaxValue : (-32768 .. 0 .. 32767)
var absValue = value == TimeSpan.MinValue ? TimeSpan.MaxValue : -value;
if (absValue.Ticks > maxTicksToRemove.Ticks)
return DateTime.MinValue;
}
return source + value;
}
看起来这个时间戳是以毫秒为单位的,请尝试下面的代码,它应该可以正常工作。
DateTime nDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
double epoch = 1585008000000;
DateTime rDate = nDateTime.AddMilliseconds(epoch);
在添加值为dynamically calculated
且将超过DateTime
范围的逻辑中,我遇到了这种情况。
double expiredAfter = Math.Pow(10, value);
var expirationDate = DateTime.UtcNow.AddSeconds(expiredAfter + 5));
在我的场景中,value
从1开始,并在每一步递增,运行10次后,它将超过DateTime
的限制。
在我的例子中,我不得不使用一个api对象作为double,并将unix时间转换为DateTime:
DateTime Date = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(Double.Parse("1596225600000"));