Python中以周为单位的GPS时间自纪元以来是多少?

8
我希望将Unix时间转换为GPS时间,即计算自GPS纪元(1980年1月6日)开始的周数。我不是要获得一年中的周数,而是从1980年开始的周数。
我的尝试是使用time.time()获取经过的秒数,返回自1970年以来已知为Unix时间的时间,并从该时刻与GPS开始日期之间经过的秒数之差减去它。
这将返回正确的值,以秒计,自1980年以来的时间,但我想要GPS周号。是否有标准的Python函数可以返回此信息?
注:GPS日期表示为自纪元以来的周数和每周内的秒数。GPS纪元不同于Unix时间戳,GPS周从星期日开始计算。注意:1980年1月6日是1980年的第一个星期日。 1 Unix时间系统的纪元是1970年1月1日00:00:00,ISO将一年中的第一周定义为“包含1月4日的那个星期”,这意味着它是第一个至少与新年重叠四天的星期。
还有其他时间系统,最著名的是J2000。从一个时间系统转换到另一个时间系统并不容易。
为了处理GPS时间,Perl提供了DateTime::Precise库,该库执行常见的时间和日期操作,并具有额外的GPS操作。问题是,Python是否提供类似的库? GPS时间维基百科条目

这个问题是一个好问题,因为它讨论了众多时间规范之一——GPS时间规范。编程语言并没有全面地解决所有不同的时间实现及其细微差别(例如GPS时间、原子时间、闰秒等)。 - Xofo
对于那些给这个问题投反对票的人,请注意这是一个严肃的问题 - 另一个类似的问题 https://dev59.com/o6Lia4cB1Zd3GeqPfC-D 也是不完整的。 - Xofo
5个回答

6

计算日期差并除以7

一种方法是使用Python的datetime模块。其中一个有用的函数是,它可以将日期转换为天数,使用date.days即可。利用这些天数,我们可以相减并除以7(一周的天数:p),以获得它们之间的周数。

但是,在将每个日期转换为天数之前,您需要首先从该date中减去该星期的第几天。这将给出该星期的Monday日期,从而消除了偏移错误。

要实现此操作,您可以执行以下操作:

from datetime import date, timedelta

epoch = date(1980, 1, 6)
today = date.today()

epochMonday = epoch - timedelta(epoch.weekday())
todayMonday = today - timedelta(today.weekday())

现在您已经获得了他们所在周的 星期一 的日期,您需要将它们相减以找到差异,并除以 7 以获取周数。

这将给出最终输出:

noWeeks = (todayMonday - epochMonday).days / 7

2
我也对这个问题很感兴趣,因为我本以为Python会有一个GPS友好的DateTime对象(可以通过方法调用输出GPS周数)。 - Xofo
这仅适用于 date 对象,对于 datetime 对象,您会得到一个偏移量。对于 datetime 对象的最简单解决方案是使用向下取整除法:(today - datetime.datetime(year=1980, month=1, day=6)) // 7 - Felix
错别字更正:(today - datetime.datetime(year=1980, month=1, day=6)).days // 7 - Felix

4

@Dave X的答案def utctoweekseconds(utc,leapseconds):很好,但是您需要在tdiff = utc -epoch -datetime.timedelta(seconds=leapseconds)中添加时间差而不是减去时间差(GPS时间超前于UTC)。如果您添加时间而不是减去,则函数将完美地工作。

当我将计算机的datetime.utcnow()通过该函数并将其与连接到设备的GPS接收器的时间进行比较时,我注意到了这一点,它们最初相差36秒(跳秒数的两倍)。

2014-09-22 21:36:52是GPS周时间164212,而不是164196(根据https://www.labsat.co.uk/index.php/en/gps-time-calculator)。

(对不起,我无法留下评论,因为我没有足够的声望)

正确的函数:

def utctoweekseconds(utc,leapseconds):
    """ Returns the GPS week, the GPS day, and the seconds 
        and microseconds since the beginning of the GPS week """
    import datetime, calendar
    datetimeformat = "%Y-%m-%d %H:%M:%S"
    epoch = datetime.datetime.strptime("1980-01-06 00:00:00",datetimeformat)
    tdiff = utc -epoch  + datetime.timedelta(seconds=leapseconds)
    gpsweek = tdiff.days // 7 
    gpsdays = tdiff.days - 7*gpsweek         
    gpsseconds = tdiff.seconds + 86400* (tdiff.days -7*gpsweek) 
    return gpsweek,gpsdays,gpsseconds,tdiff.microseconds

2
一种反函数已经在gist上提供了:https://gist.github.com/jeremiahajohnson/eca97484db88bcf6b124
def weeksecondstoutc(gpsweek,gpsseconds,leapseconds):
    import datetime, calendar
    datetimeformat = "%Y-%m-%d %H:%M:%S"
    epoch = datetime.datetime.strptime("1980-01-06 00:00:00",datetimeformat)
  # correction per https://dev59.com/RaPia4cB1Zd3GeqP5-1Y#54520579

    elapsed = datetime.timedelta(days=(gpsweek*7),seconds=(gpsseconds-leapseconds))
    return datetime.datetime.strftime(epoch + elapsed,datetimeformat)


weeksecondstoutc(1811,164196.732,16) 
## --> '2014-09-22 21:36:20'

请注意,此解决方案手动考虑了 POSIX 和 TAI 之间闰秒的差异。(有关闰秒,请参见https://en.wikipedia.org/wiki/Leap_second)闰秒可从https://stackoverflow.com/a/33445945/1653571中获取,但此代码未使用它。因此,将 Unix 时间转换回 GPS 也需要考虑闰秒。
def utctoweekseconds(utc,leapseconds):
    """ Returns the GPS week, the GPS day, and the seconds 
            and microseconds since the beginning of the GPS week """
    import datetime, calendar
    datetimeformat = "%Y-%m-%d %H:%M:%S"
    epoch = datetime.datetime.strptime("1980-01-06 00:00:00",datetimeformat)
  #  tdiff = utc -epoch -datetime.timedelta(seconds=leapseconds)
  # correction per https://dev59.com/RaPia4cB1Zd3GeqP5-1Y#54520579
    tdiff = utc -epoch  + datetime.timedelta(seconds=leapseconds)
    gpsweek = tdiff.days // 7 
    gpsdays = tdiff.days - 7*gpsweek         
    gpsseconds = tdiff.seconds + 86400 * (tdiff.days -7*gpsweek) 
    return (gpsweek,gpsdays,gpsseconds,tdiff.microseconds)
        


utctoweekseconds(datetime.datetime.strptime('2014-09-22 21:36:20',"%Y-%m-%d %H:%M:%S"),16)
## gives: (1811, 1, 164196, 0)

我还需要GPS周的日期,因为我正在从https://cddis.nasa.gov/Data_and_Derived_Products/GNSS/orbit_and_clock_products.html等网站计算GPS时钟和轨道文件的文件名。
根据https://dev59.com/RaPia4cB1Zd3GeqP5-1Y#54520579更新的答案。请注意,如果第二个函数需要符号更改,则从代码片段复制的代码也需要更改。

1
您可以通过以下方式尝试使用gnsscal模块:

$ pip install gnsscal

然后像这样使用它:

>>> import gnsscal
>>> import datetime
>>> day = datetime.date(2019, 2, 22)
>>> gnsscal.date2gpswd(day)
(2041, 5)

但是如果您想将UTC时间转换为GPS时间,需要考虑到闰秒的差异,您可以从IERS获取闰秒信息。


1

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