how to create datetime from a negative epoch in Python

Question:

First timer on StackExchange.

I am working with ArcGIS Server and Python. While trying to execute a query using the REST endpoint to a map service, I am getting the values for a field that is esriFieldTypeDate in negative epoch in the JSON response.
The JSON response looks like this:

    {
  "feature" :
  {
    "attributes" : {
      "OBJECTID" : 11,
      "BASIN" : "North Atlantic",
      "TRACK_DATE" : -3739996800000,
    }
    ,
    "geometry" :
    {
      "paths" :
      [
        [
          [-99.9999999999999, 30.0000000000001],
          [-100.1, 30.5000000000001]
        ]
      ]
    }
  }
}

The field I am referring to is “TRACK_DATE” in the above JSON. The values returned by ArcGIS Server are always in milliseconds since epoch. ArcGIS Server also provides a HTML response and the TRACK_DATE field for the same query is displayed as “TRACK_DATE: 1851/06/27 00:00:00 UTC”.

So, the date is pre 1900 and I understand the Python in-built datetime module is not able to handle dates before 1900. I am using 32-bit Python v2.6. I am trying to convert it to a datetime by using

datetime.datetime.utcfromtimestamp(float(-3739996800000)/1000)

However, this fails with

ValueError: timestamp out of range for platform localtime()/gmtime() function

How does one work with epochs that are negative and pre 1900 in Python 2.6? I have looked at similar posts, but could not find one that explains working with negative epochs.

Asked By: Anand

||

Answers:

This works for me:

datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=(-3739996800000/1000))

datetime.datetime(1851, 6, 27, 0, 0)

This would have been better asked on StackOverflow since it is more Python specific than it is GIS-specific.

Answered By: Jason Scheirer
if timestamp < 0:
    return datetime(1970, 1, 1) + timedelta(seconds=timestamp)
else:
    return datetime.utcfromtimestamp(timestamp)
Answered By: DaveSawyer

You can accomplish this using the datetime module’s datetime and timedelta functions.

The other answers divide the timestamp by 1000 to convert milliseconds to seconds. This is unnecessary, since the timedelta function can take milliseconds directly as a parameter. It might therefore be cleaner to do something like this:

datetime.datetime(1970, 1, 1) + datetime.timedelta(milliseconds=-3739996800000)

which gives datetime.datetime(1851, 6, 27, 0, 0), as you’d expect.

Answered By: Trond Humborstad

The fromtimestamp() and the utcfromtimestamp() methods have been updated now to handle negative timestamps.
You can directly use the fromtimestamp() method in the datetime module to convert the epoch to datetime. Don’t forget to convert the milliseconds to seconds. Remember, the fromtimestamp() method will give a datetime object according to your timezone.

To calculate the datetime object in UTC time, you can use the utcfromtimestamp() method.

Answered By: Aditya Raj
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.