从 2000 年 1 月 1 日开始从 UNIX 时间转换为时间戳

Conversion from UNIX time to timestamp starting in January 1, 2000

我正在尝试与一个 API 进行交互,该 API 使用的时间戳与 UNIX 纪元的开始时间不同。它似乎从 2000-01-01 开始计算,但我不确定具体如何进行转换或这种日期时间格式的名称是什么。

当我在 1456979510 发送一条消息时,我收到回复说它已在 510294713 收到。
两者相差946684796(有时946684797)秒,也就是大约30年

谁能告诉我两者之间转换的正确方法?或者我是否可以在 Python?

中直接生成它们

谢谢

编辑

我应该提到的另一个细节是,这是一个 API Zigbee 设备。我在他们的文档中找到了以下数据类型条目:

1.3.2.7 Absolute time
This is an unsigned 32-bit integer representation for absolute time. Absolute time is measured in seconds from midnight, 1st January 2000.

我仍然不确定在两者之间转换的最简单方法

编辑:OP 添加了详细信息,指定时间从 午夜 开始,因此它是 绝对 与 J2000 的时间不同,J2000 从 中午 开始。但由于标题说明 "timestamp starting in January 1, 2000" 我让这个答案供未来的答案寻求者使用。

答案:

您提到的时间戳似乎是提到的 J2000.0 here

由于 Unix 和 J2000 纪元时间是常量,您可以定义一个常量来存储差异。

如果您有数学兴趣,以下链接提供了一些关于转换的信息

  1. http://www.giss.nasa.gov/tools/mars24/help/algorithm.html参考步骤A-2
  2. http://onegeek.org/software/smeg/current/src/time.c(C文件),

    C 文件中的 #define 部分包含以下内容

    #define J2000 2451545.0 /* you-know-when */

    #define U1970 -10957.5 /* unix epoch relative to J2000 */

嗯,2000-01-01T00:00:00Z 和 1970-01-01T00:00:00Z 之间有 946684800 秒。因此,您只需为 946684800 设置一个常量,然后从您的 Unix 时间戳中添加或减去。

您在数字中看到的变化与发送和接收数据的延迟有关,也可能是由于时钟同步或不同步造成的。由于这些是整秒,而你的数字有 3 到 4 秒的偏差,那么我猜你的计算机和设备之间的时钟也有 3 到 4 秒的不同步。

时间 1970 年 1 月 00:00:00 被认为是 UNIX epoch。因此,如果您想将 UNIX 时间转换为纪元为 2000 年 1 月 1 日的时间戳(假设为 2000 年纪元),最简单的方法就是简单地从 UNIX 时间中减去 2000 年 1 月 1 日的 UNIX 时间。

<2000 time> = <UNIX time> - <January 1, 2000 UNIX time>

<UNIX time> = <2000 time> + <January 1, 2000 UNIX time>

其中 2000 年 1 月 1 日 UNIX 时间是 946684800.

编辑: 文档确实说

Absolute time is measured in seconds from midnight, 1st January 2000.

所以,946684800 是应该用来计算的 确切时间差 。您计算出的几秒差异可能是由于网络延迟或其他一些延迟造成的。

两次确实相差30年:

>>> import datetime
>>> d1 = datetime.datetime.fromtimestamp(1456979510)
>>> d1.ctime()
'Wed Mar  2 20:31:50 2016'
>>> d2 = datetime.datetime.fromtimestamp(510294713)
>>> d2.ctime()
'Mon Mar  3 20:31:53 1986'

可以创建一个变量来保存两种方式的差异转换:

>>> conv_factor = (d1 - d2).total_seconds()
>>> conv_factor
946684797.0
>>> conv_time = d2 + datetime.timedelta(seconds=conv_factor)
>>> conv_time
datetime.datetime(2016, 3, 2, 20, 31, 50)
>>> conv_time.ctime()
'Wed Mar  2 20:31:50 2016'

减去 conv_factor 可以转换另一个方向。

Unix 纪元:1970-1-1,00:00:00 UTC

J2000 纪元:2000-1-1,12:00:00 UTC

时间间隔为:946684800秒

陷阱是 python 将使用本地时区从日期时间转换为时间戳。如下图:

import datetime
import time, calendar
dt = datetime.datetime(1970, 1, 1, 0, 0) # datetime.datetime, default is computer's local time zone
tt = dt.timetuple()
print(tt) # time.struct_time
print("Unix Timestamp: ",time.mktime(tt))      # struct_time in local time
print("Unix Timestamp: ",calendar.timegm(tt))  # struct_time in UTC

因此,如果您想将时间戳转换回日期时间,请使用这些代码:

t = 0  # Unix timestamp
t2000 = t+946728000
#value = datetime.datetime.fromtimestamp(t2000)   # from local time
dt= datetime.datetime.utcfromtimestamp(t2000)     # from UTC time
print(dt.timetuple())
print(dt.strftime('%Y-%m-%d %H:%M:%S'))

网上有个不错的转换工具:https://www.unixtimestamp.com/index.php