Добавление секунд в 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;
}