Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have gps unsegmented time like this:

Tgps = 1092121243.0

And I'd like to understand what date and time is that. The begining of GPS time is 6 January 1980. Python function

datetime.utcfromtimestamp 

could give seconds from 1 January 1970 year.

I found following:

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)

I'm not sure about leapseconds are they included in function datetime or I should calculate them and substract from the result? May be also exists better solution of this problem?

like image 290
Anton Protopopov Avatar asked Oct 29 '15 13:10

Anton Protopopov


People also ask

How do you get the current time in a string in python?

You can get the current time in string format by using the datetime. now(). strftime(“%H:%M:%S”).

What is GPS timestamp?

GPS reference time is referenced to UTC with zero point defined as midnight on the night of January 5, 1980. The time stamp consists of the number of weeks since that zero point and the number of seconds since the last week number change (0 to 604,799).

Is datetime in UTC Python?

Practical Data Science using PythonYou can use the datetime module to convert a datetime to a UTC timestamp in Python. If you already have the datetime object in UTC, you can the timestamp() to get a UTC timestamp. This function returns the time since epoch for that datetime object.


2 Answers

GPS time started in sync with UTC: 1980-01-06 (UTC) == 1980-01-06 (GPS). Both tick in SI seconds. The difference between GPS time and UTC time increases with each (intercalary) leap second.

To find the correct UTC time, you need to know the number of leap seconds occurred before the given GPS time:

#!/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) is the number of leap seconds introduced before the given date. From TAI-UTC table (note: the site is the authoritative source on leap seconds. It publishes Bulletin C announcing new leap seconds):

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

and therefore:

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

If you are on Unix then you could use "right" time zone to get UTC time from TAI time (and it is easy to get TAI time from GPS time: TAI = GPS + 19 seconds (constant offset)):

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

You could avoid changing the timezone if you extract the leap seconds list from the corresponding tzfile(5). It is a combination of the first two methods where the leap count computation from the first method is automated and the autoupdating tzdata (system package for the tz database) from the second method is used:

>>> 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 can extract leap seconds from /usr/share/zoneinfo/right/UTC file (part of tzdata package).

All three methods produce the same result.

like image 193
jfs Avatar answered Oct 09 '22 20:10

jfs


You can use the astropy.time package to do this:

GPS time to TAI

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

which returns 2014-08-15 07:01:02.000

GPS time to 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)

which outputs 2014-08-15 07:00:27.000

like image 36
Ru887321 Avatar answered Oct 09 '22 20:10

Ru887321