how to create datetime from a negative epoch in Python
Asked Answered
P

4

9

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.

Pro answered 21/6, 2013 at 7:34 Comment(0)
B
15

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.

Bunyan answered 21/6, 2013 at 8:36 Comment(0)
S
6
if timestamp < 0:
    return datetime(1970, 1, 1) + timedelta(seconds=timestamp)
else:
    return datetime.utcfromtimestamp(timestamp)
Supercargo answered 2/3, 2014 at 2:20 Comment(0)
S
2

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.

Sesquicarbonate answered 16/7, 2015 at 13:12 Comment(0)
F
0

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.

Febrific answered 23/1, 2023 at 18:2 Comment(2)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Caribbean
It is OS-dependent. On my windows machine datetime.datetime.fromtimestamp(-3739996800000//1000) raises OSError: [Errno 22] Invalid argument. On my Linux machine it returns datetime.datetime(1851, 6, 27, 0, 0) as expected.Transaction

© 2022 - 2024 — McMap. All rights reserved.