簡體   English   中英

如何從python中的GPS未分段時間獲取當前日期和時間

[英]How to get current date and time from GPS unsegment time in python

我有這樣的 gps 未分段時間:

Tgps = 1092121243.0

我想知道那是什么日期和時間。 GPS的開始時間是1980年1月6日。 Python function

datetime.utcfromtimestamp 

可以給出從 1 January 1970 年開始的秒數。

我發現以下內容:

from datetime import datetime
GPSfromUTC = (datetime(1980,1,6) - datetime(1970,1,1)).total_seconds()
curDate = datetime.utcfromtimestamp(Tgps + GPSfromUTC) 

Out[83]: datetime.datetime(2014, 8, 15, 7, 0, 43)

我不確定閏秒是否包含在 function 日期時間中,或者我應該計算它們並從結果中減去? 可能還存在更好的解決這個問題的方法嗎?

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)

輸出

2014-08-15 07:00:27 # (UTC)

其中leap_count(date)是在給定日期之前引入的閏秒數。 來自TAI-UTC 表(注意:該站點是閏秒的權威來源。它發布公告 C 宣布新的閏秒):

1980..: 19s 
2012..: 35s

因此:

(leap_count(2014) - leap_count(1980)) == (35 - 19)

如果您使用的是 Unix,那么您可以使用"right"時區從 TAI 時間獲取 UTC 時間(並且很容易從 GPS 時間獲取 TAI 時間: TAI = GPS + 19 秒(恆定偏移量) ):

#!/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!

輸出

2014-08-15 07:00:27 # (UTC)

如果從相應的tzfile(5)提取閏秒列表,則可以避免更改時區。 它是前兩種方法的組合,其中第一種方法的跳躍計數計算是自動的,並且使用第二種方法的自動更新tzdatatz 數據庫的系統包):

>>> 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)

其中leapseconds.py可以從/usr/share/zoneinfo/right/UTC文件( tzdata包的一部分)中提取閏秒。

所有三種方法都會產生相同的結果。

你可以使用astropy.time包來做到這一點:

到 TAI 的 GPS 時間

from astropy.time import Time
mytime = 1092121243.0
t = Time(mytime, format='gps')
t = Time(t, format='iso') # same as scale='tai'
print(t)

返回2014-08-15 07:01:02.000

GPS 時間到 UTC

from astropy.time import Time
sec = 1092121243.0
t_in = Time(sec, format='gps')
t_out = Time(t_in, format='iso', scale='utc')
print(t_out)

輸出2014-08-15 07:00:27.000

我使用以下計算閏秒的函數:

import bisect
from datetime import datetime, timedelta

_LEAP_DATES = ((1981, 6, 30), (1982, 6, 30), (1983, 6, 30),
               (1985, 6, 30), (1987, 12, 31), (1989, 12, 31),
               (1990, 12, 31), (1992, 6, 30), (1993, 6, 30),
               (1994, 6, 30), (1995, 12, 31), (1997, 6, 30),
               (1998, 12, 31), (2005, 12, 31), (2008, 12, 31),
               (2012, 6, 30), (2015, 6, 30), (2016, 12, 31))

LEAP_DATES = tuple(datetime(i[0], i[1], i[2], 23, 59, 59) for i in _LEAP_DATES)

def leap(date):
    """
    Return the number of leap seconds since 1980-01-01

    :param date: datetime instance
    :return: leap seconds for the date (int)
    """
    # bisect.bisect returns the index `date` would have to be
    # inserted to keep `LEAP_DATES` sorted, so is the number of
    # values in `LEAP_DATES` that are less than `date`, or the
    # number of leap seconds.
    return bisect.bisect(LEAP_DATES, date)

當然,您偶爾需要更新_LEAP_DATES ,但這些更新非常罕見。

一般來說,GPS 時間由兩個數字組成: GPS 周和自當前 GPS 周開始以來的秒數 因此,您可以使用以下方法:

def gps2utc(week, secs):
    """
    :param week: GPS week number, i.e. 1866
    :param secs: number of seconds since the beginning of `week`
    :return: datetime instance with UTC time
    """
    secs_in_week = 604800
    gps_epoch = datetime(1980, 1, 6, 0, 0, 0)
    date_before_leaps = gps_epoch + timedelta(seconds=week * secs_in_week + secs)
    return date_before_leaps - timedelta(seconds=leap(date_before_leaps))

在你的情況下week = 0 ,所以:

In [1]: gps2utc(0, 1092121243.0)
Out[1]: datetime.datetime(2014, 8, 15, 7, 0, 27)

Ru887321Yury Kirienko之間的線性組合答案。

from astropy.time import Time

def gps2utc(gpsweek, gpsseconds):
    """ GPS time to UTC.

    Parameters
    ----------
    gpsweek : int
        GPS week number, i.e. 1866.
    gpsseconds : int
        Number of seconds since the beginning of week.

    Returns
    -------
    datetime
        datetime instance with UTC time.
    """
    secs_in_week = 604800
    secs = gpsweek * secs_in_week + gpsseconds

    t_gps = Time(secs, format="gps")
    t_utc = Time(t_gps, format="iso", scale="utc")

    return t_utc.datetime

在你的情況下week = 0 ,所以:

In [1]: gps2utc(0, 1092121243.0)
Out[1]: datetime.datetime(2014, 8, 15, 7, 0, 27)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM