GPS 时间开始与 UTC 同步:1980-01-06 (UTC) == 1980-01-06 (GPS)
。两者均以 SI 秒为单位。 GPS 时间和 UTC 时间之间的差异随着每个(闰秒)闰秒而增加。
要找到正确的 UTC 时间,您需要知道给定 GPS 时间之前发生的闰秒数:
#!/usr/bin/env python
from datetime import datetime, timedelta
# utc = 1980-01-06UTC + (gps - (leap_count(2014) - leap_count(1980)))
utc = datetime(1980, 1, 6) + timedelta(seconds=1092121243.0 - (35 - 19))
print(utc)
Output
2014-08-15 07:00:27 # (UTC)
where leap_count(date)
是给定日期之前引入的闰秒数。从(注:该网站是闰秒的权威来源。它发布公告 C 宣布新的闰秒 http://hpiers.obspm.fr/eop-pc/index.php?index=bulletins):
1980..: 19s
2012..: 35s
因此:
(leap_count(2014) - leap_count(1980)) == (35 - 19)
如果你使用的是 Unix 那么你可以使用"right"
从 TAI 时间获取 UTC 时间的时区
(并且很容易从 GPS 时间获得 TAI 时间:TAI = GPS + 19 秒(恒定偏移) http://www.leapsecond.com/java/gpsclock.htm):
#!/usr/bin/env python
import os
import time
os.environ['TZ'] = 'right/UTC' # TAI scale with 1970-01-01 00:00:10 (TAI) epoch
time.tzset() # Unix
from datetime import datetime, timedelta
gps_timestamp = 1092121243.0 # input
gps_epoch_as_gps = datetime(1980, 1, 6)
# by definition
gps_time_as_gps = gps_epoch_as_gps + timedelta(seconds=gps_timestamp)
gps_time_as_tai = gps_time_as_gps + timedelta(seconds=19) # constant offset
tai_epoch_as_tai = datetime(1970, 1, 1, 0, 0, 10)
# by definition
tai_timestamp = (gps_time_as_tai - tai_epoch_as_tai).total_seconds()
print(datetime.utcfromtimestamp(tai_timestamp)) # "right" timezone is in effect!
Output
2014-08-15 07:00:27 # (UTC)
如果从相应的时间中提取闰秒列表,则可以避免更改时区tzfile(5) http://man7.org/linux/man-pages/man5/tzfile.5.html。它是前两种方法的组合,其中第一种方法的跳跃计数计算是自动的,并且自动更新tzdata
(系统包为tz 数据库 https://en.wikipedia.org/wiki/Tz_database)使用第二种方法:
>>> from datetime import datetime, timedelta
>>> import leapseconds
>>> leapseconds.gps_to_utc(datetime(1980,1,6) + timedelta(seconds=1092121243.0))
datetime.datetime(2014, 8, 15, 7, 0, 27)
where leapseconds.py https://gist.github.com/zed/92df922103ac9deb1a05可以从中提取闰秒/usr/share/zoneinfo/right/UTC
文件(部分tzdata
包裹)。
所有三种方法都会产生相同的结果。