.net 使用有效的Double将秒数添加到DateTime会导致ArgumentOutOfRangeException

uplii1fm  于 2023-05-08  发布在  .NET
关注(0)|答案(8)|浏览(152)

下面的代码崩溃和烧毁,我不明白为什么:

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纪元时间戳。* “令牌发布的时间,表示为自Unix纪元(1970年1月1日00:00:00 UTC)以来的秒数。"*

解决方案

Salesforce REST API实际上在执行OAuth请求时为issued_at字段发送 * 毫秒 *,而他们说他们正在发送秒...

bakd9h0s

bakd9h0s1#

正如其他人所说,问题在于价值太大。
看过它之后,我相信它表示自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-但显然这会丢失数据。

cnjp1d6j

cnjp1d6j2#

添加的值导致日期超出DateTime支持的有效日期范围。
DateTime支持01/01/0001 00:00:00到31/12/9999 23:59:59。
简单地计算1332958778172/3600/24/365,得到42267年。

3ks5zfa0

3ks5zfa03#

我认为双倍的价值确实太大了。它表示刚好超过42,267年(如果我的计算正确的话),DateTime.MaxValue是23:59:59.999999,December 31,9999

hrirmatl

hrirmatl4#

DateTime dt = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);    
Console.Write(dt.AddSeconds(1332958778172D));

除了...
1332958778172/60/60/24/365 = 42,267年……其中DateTime最多只能到23:59:59.999999,December 31,9999

daolsyd0

daolsyd05#

我有一个类似的问题,我被要求添加一个可配置的时间跨度到日期时间。如果配置不正确,我必须假设“最坏的情况”:最大值
我通过实现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;
    }
mo49yndu

mo49yndu6#

看起来这个时间戳是以毫秒为单位的,尝试下面的代码应该可以正常工作。

DateTime nDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
double epoch = 1585008000000;
DateTime rDate = nDateTime.AddMilliseconds(epoch);
s2j5cfk0

s2j5cfk07#

这发生在我的逻辑中,其中添加的值是dynamically calculated,并且它将超过DateTime范围。

double expiredAfter = Math.Pow(10, value);
        
var expirationDate = DateTime.UtcNow.AddSeconds(expiredAfter + 5));

在我的场景中,value从1开始,每一步递增,运行10次后,它将超过DateTime的限制。

qvtsj1bj

qvtsj1bj8#

在我的例子中,我必须使用一个API对象作为double,并将unix时间转换为DateTime:

DateTime Date = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(Double.Parse("1596225600000"));

相关问题