Добавление секунд в DateTime с действительными двойными результатами в ArgumentOutOfRangeException

Следующий код сбой и ожоги, и я не понимаю, почему:

DateTime dt = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);
double d = double.Parse("1332958778172");

Console.Write(dt.AddSeconds(d));

Может ли кто-нибудь сказать мне, что происходит? Я просто не могу понять, почему...

РЕДАКТИРОВАТЬ

Это значение возвращается из API Salesforce REST и из того, что я понимаю, это отметка времени эпохи Unix. "Время маркерной эмиссии, представленное как количество секунд с момента Unix (00:00:00 UTC 1 января 1970 года)".

РЕШЕНИЕ

Salesforce REST API фактически отправляет миллисекунды назад для поля issued_at при выполнении запроса OAuth, когда говорят, что они отправляют секунды...

Ответ 1

Как говорили другие, проблема в том, что значение слишком велико.

Просмотрев его, я считаю, что он представляет миллисекунды с эпохи 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));

Либо это, либо разделите на 1000 до вызова AddSeconds но, очевидно, это потеряет данные.

Ответ 2

Значение, которое вы добавляете, приводит к дате за пределами допустимого диапазона дат, поддерживаемых DateTime.

DateTime поддерживает 01/01/0001 00:00:00 - 31/12/9999 23:59:59.

Простой расчет 1332958778172/3600/24/365 дает 42267 лет.

Ответ 3

Я думаю, что двойное значение действительно слишком велико. Он составляет чуть более 42 267 лет (если мои математические данные верны), а DateTime.MaxValue - 23: 59: 59.9999999, 31 декабря, 9999

Ответ 4

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.9999999, 31 декабря, 9999

Ответ 5

У меня была аналогичная проблема, когда мне нужно было добавить настраиваемый промежуток времени в datetime. Если конфигурация неверна, я должен принять "худший сценарий": 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;
    }