16

The following code crashes and burns and I don't understand why:

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

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

Can someone tell me what's going on? I just can't seem to be able to figure out why...

EDIT

This value comes back from the Salesforce REST API and from what I understand it's a Unix epoch time stamp. "The time of token issue, represented as the number of seconds since the Unix epoch (00:00:00 UTC on 1 January 1970)."

SOLUTION

Salesforce REST API is in fact sending milliseconds back for the issued_at field when performing the OAuth request when they say they're sending seconds...

Gup3rSuR4c
  • 9,145
  • 10
  • 68
  • 126
  • What is the error/exception you get? – Mathieu Mar 28 '12 at 19:06
  • That double value can result in you trying to add `1332958778172.00000000000004` seconds(because of how doubles are handled) this would cause the out of range exception. Also this passes the number of years a DT can handle. – jzworkman Mar 28 '12 at 19:07

8 Answers8

19

As others have said, the problem is that the value is too large.

Having looked over it, I believe it represents milliseconds since the Unix epoch, not seconds so you want:

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));

Either that, or divide by 1000 before calling AddSeconds - but obviously that will lose data.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
8

The value you are adding results in a date outside of the valid range of dates that a DateTime supports.

DateTime supports 01/01/0001 00:00:00 to 31/12/9999 23:59:59.

A simple calculation of 1332958778172/3600/24/365 gives 42267 years.

Phil
  • 42,255
  • 9
  • 100
  • 100
3

I think the double value is genuinely too large. It represents just over 42,267 years (if my maths is correct), and DateTime.MaxValue is 23:59:59.9999999, December 31, 9999

KazR
  • 961
  • 7
  • 16
2
DateTime dt = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);    
Console.Write(dt.AddSeconds(1332958778172D));

Except that...

1332958778172/60/60/24/365 = 42,267 years... which DateTime can only go up to 23:59:59.9999999, December 31, 9999

Hupperware
  • 979
  • 1
  • 6
  • 15
1

I had a similar issue where I was required to add a configurable timespan to a datetime. If the configuration is not correct I have to assume the 'worst scenario' : MaxValue.

I solved it by implementing an extension to DateTime (still in test phase) :

    /// <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;
    }
Gauthier
  • 21
  • 2
0

Looks like this timestamp is in milliseconds, try below code it should work fine.

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

This happened to me in a logic where the value added was dynamically calculated and it would exceed the DateTime range.

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

In my scenario value was starting from 1 and incremented at each step, and after 10 runs it would exceed the DateTime limit.

Cata Hotea
  • 1,811
  • 1
  • 9
  • 19
-1

In my case I had to consume an api object as a double and convert the unix time to a DateTime:

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