如何在Python中从负纪元创建日期时间

9

我是StackExchange的新手。

我正在使用ArcGIS Server和Python工作。当我尝试使用REST端点对地图服务进行查询时,我在JSON响应中得到了一个esriFieldTypeDate类型字段的负纪元值。 JSON响应如下:

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

我所指的字段是上述JSON中的“TRACK_DATE”。ArcGIS Server返回的值始终是自纪元以来的毫秒数。ArcGIS Server还提供HTML响应,对于相同的查询,TRACK_DATE字段显示为“TRACK_DATE: 1851/06/27 00:00:00 UTC”。
因此,该日期早于1900年,并且我了解到Python内置的datetime模块无法处理1900年之前的日期。 我正在使用32位Python v2.6尝试按如下方式将其转换为日期时间:
datetime.datetime.utcfromtimestamp(float(-3739996800000)/1000)
但是,此方法失败并出现以下错误信息:
ValueError: timestamp out of range for platform localtime()/gmtime() function

如何在Python 2.6中处理负数和1900年以前的时代?我查看了类似的帖子,但没有找到解释处理负数时代的。

4个回答

14

这对我有用:

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

这个问题最好在StackOverflow上提问,因为它更偏向于Python而不是GIS。

这个问题更适合在StackOverflow上提问,因为它更侧重于Python而不是GIS。


6
if timestamp < 0:
    return datetime(1970, 1, 1) + timedelta(seconds=timestamp)
else:
    return datetime.utcfromtimestamp(timestamp)

2
你可以使用 datetime 模块的 datetimetimedelta 函数来实现此操作。
其他答案将时间戳除以1000以将毫秒转换为秒。这是不必要的,因为 timedelta 函数可以直接将毫秒作为参数。因此,可能更清晰的做法是这样的:
datetime.datetime(1970, 1, 1) + datetime.timedelta(milliseconds=-3739996800000)

这会给出datetime.datetime(1851, 6, 27, 0, 0),就像你所期望的那样。


0

fromtimestamp()和utcfromtimestamp()方法现在已经更新,可以处理负时间戳。 您可以直接使用datetime模块中的fromtimestamp()方法将纪元转换为日期时间。不要忘记将毫秒转换为秒。请记住,fromtimestamp()方法将根据您的时区提供一个日期时间对象。

要计算UTC时间的日期时间对象,您可以使用utcfromtimestamp()方法。


你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community
这是与操作系统相关的。在我的Windows机器上,datetime.datetime.fromtimestamp(-3739996800000//1000)会引发OSError: [Errno 22] Invalid argument错误。而在我的Linux机器上,它会返回预期的datetime.datetime(1851, 6, 27, 0, 0) - AXO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接