2

As I understand for now in python there is no function to get leap seconds from gps epoch for current date. The appropriate patch under investigation/development: leap seconds path in datetime

Could you advice the best way how to get leap seconds? I found that solution:

def getLeapSec(Tgps):
  daysFromGPSEpoch = timedelta(seconds=Tgps).days
  tableLeapSec = ([
    [0,  542,  907, 1272, 2003, 2917, 3648, 4013, 4560, 4925, 5290, 5839, 6386, 6935, 9492, 10588, 11865, 12960],
    [0,    1,    2,    3,    4,    5,    6,    7,    8,    9,   10,   11,   12,   13,   14,    15,    16,    17]
                 ])

  for i in range(1, len(tableLeapSec[0])):
    if daysFromGPSEpoch < tableLeapSec[0][i]:
      return tableLeapSec[1][i-1]

Example:

In [25]: Tgps = 1092121243.0

In [26]: getLeapSec(Tgps)
Out[26]: 16
Anton Protopopov
  • 30,354
  • 12
  • 88
  • 93
  • 1
    related: [Extract historic leap seconds from tzdata](http://stackoverflow.com/q/19332902/4279) – jfs Oct 30 '15 at 16:31
  • btw, the Python issue you've linked is unrelated to how you could get the number of leap seconds for a date. – jfs Oct 30 '15 at 16:32
  • Yes, thank you. I didn't read description of that patch correctly. About [leap secs from tzdata](http://stackoverflow.com/questions/19332902/extract-historic-leap-seconds-from-tzdata), as I understand it could be implemented only on unix/linux platform but no on Windows as I need. – Anton Protopopov Oct 30 '15 at 19:03
  • the reason to use tzfile from `tzdata` system package (or similar) is that it is updated automatically i.e., you don't need to touch your code when the next positive leap second is introduced. The tzfile itself does not depend on the platform i.e., [`leapseconds.py`](https://gist.github.com/zed/92df922103ac9deb1a05) would work on Windows if you give it the file (see [the example usage at the end of my answer](http://stackoverflow.com/a/33426779/4279)). Find out whether there is an autoupdating leap seconds table on Windows (perhaps in a different format).. – jfs Oct 30 '15 at 22:26
  • ..continued: Otherwise, you can [get TAI-UTC from IERS](http://hpiers.obspm.fr/eop-pc/index.php?index=TAI-UTC_tab&lang=en) – jfs Oct 30 '15 at 22:26

1 Answers1

1

You could use leapseconds module if you have access to the up-to-date tzfile on your system:

>>> from datetime import datetime, timedelta
>>> import leapseconds
>>> Tgps = 1092121243.0
>>> gps_time = datetime(1980, 1, 6) + timedelta(seconds=Tgps)
>>> leapseconds.dTAI_UTC_from_tai(leapseconds.gps_to_tai(gps_time))
datetime.timedelta(0, 35)

The main advantage is that tzdata package is updated several times per year by the system automatically (more often than leap seconds are introduced). Your code will use the new data without the need to change it.

Otherwise, as a fallback, you could hardcode the result of the leapseconds.leapseconds() call:

>>> import leapseconds
>>> leapseconds.leapseconds()
[LeapSecond(utc=datetime.datetime(1972, 1, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 10)),
 LeapSecond(utc=datetime.datetime(1972, 7, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 11)),
 LeapSecond(utc=datetime.datetime(1973, 1, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 12)),
 LeapSecond(utc=datetime.datetime(1974, 1, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 13)),
 LeapSecond(utc=datetime.datetime(1975, 1, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 14)),
 LeapSecond(utc=datetime.datetime(1976, 1, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 15)),
 LeapSecond(utc=datetime.datetime(1977, 1, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 16)),
 LeapSecond(utc=datetime.datetime(1978, 1, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 17)),
 LeapSecond(utc=datetime.datetime(1979, 1, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 18)),
 LeapSecond(utc=datetime.datetime(1980, 1, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 19)),
 LeapSecond(utc=datetime.datetime(1981, 7, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 20)),
 LeapSecond(utc=datetime.datetime(1982, 7, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 21)),
 LeapSecond(utc=datetime.datetime(1983, 7, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 22)),
 LeapSecond(utc=datetime.datetime(1985, 7, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 23)),
 LeapSecond(utc=datetime.datetime(1988, 1, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 24)),
 LeapSecond(utc=datetime.datetime(1990, 1, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 25)),
 LeapSecond(utc=datetime.datetime(1991, 1, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 26)),
 LeapSecond(utc=datetime.datetime(1992, 7, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 27)),
 LeapSecond(utc=datetime.datetime(1993, 7, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 28)),
 LeapSecond(utc=datetime.datetime(1994, 7, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 29)),
 LeapSecond(utc=datetime.datetime(1996, 1, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 30)),
 LeapSecond(utc=datetime.datetime(1997, 7, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 31)),
 LeapSecond(utc=datetime.datetime(1999, 1, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 32)),
 LeapSecond(utc=datetime.datetime(2006, 1, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 33)),
 LeapSecond(utc=datetime.datetime(2009, 1, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 34)),
 LeapSecond(utc=datetime.datetime(2012, 7, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 35)),
 LeapSecond(utc=datetime.datetime(2015, 7, 1, 0, 0), dTAI_UTC=datetime.timedelta(0, 36))]

You have to update the list manually when the next leap second is introduced in this case.

The authoritative source for the leap seconds updates is Bulletin C issued by IERS that also provides TAI-UTC data since 1961.

You could ping IESR once in a half-year (e.g., January, July), to find out programmatically using leap_second_client.py when the next leap second is scheduled.

jfs
  • 399,953
  • 195
  • 994
  • 1,670