Source code for pyacs.lib.gpstime

"""
Note: Leap seconds still needs to be checked an improve
A Python implementation of GPS related time conversions.

Copyright 2002 by Bud P. Bruegger, Sistema, Italy
mailto:bud@sistema.it
http://www.sistema.it

Modifications for GPS seconds by Duncan Brown

PyUTCFromGpsSeconds added by Ben Johnson

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option) any
later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
details.

You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA  02111-1307  USA

GPS Time Utility functions

This file contains a Python implementation of GPS related time conversions.

The two main functions convert between UTC and GPS time (GPS-week, time of
week in seconds, GPS-day, time of day in seconds).  The other functions are
convenience wrappers around these base functions.  

A good reference for GPS time issues is:
http://www.oc.nps.navy.mil/~jclynch/timsys.html

Note that python time types are represented in seconds since (a platform
dependent Python) Epoch.  This makes implementation quite straight forward
as compared to some algorigthms found in the literature and on the web.  
"""

__author__ = 'Duncan Brown <duncan@gravity.phys.uwm.edu>'
__date__ = '$Date: 2006/02/16 04:36:09 $'
__version__ = '$Revision: 1.6 $'[11:-2]

import time, math

secsInWeek = 604800
secsInDay = 86400
gpsEpoch = (1980, 1, 6, 0, 0, 0)  # (year, month, day, hh, mm, ss)

[docs] def dayOfWeek(year, month, day): """Return GPS day of week: 0=Sun, 1=Mon, ..., 6=Sat. Parameters ---------- year, month, day : int Date components. Returns ------- int Day of week (0-6). """ hr = 12 #make sure you fall into right day, middle is save t = time.mktime((year, month, day, hr, 0, 0.0, 0, 0, -1)) pyDow = time.localtime(t)[6] gpsDow = (pyDow + 1) % 7 return gpsDow
[docs] def gpsWeek(year, month, day): """Return full GPS week number for given UTC date. Parameters ---------- year, month, day : int UTC date. Returns ------- int GPS week number. """ hr = 12 #make sure you fall into right day, middle is save #print "toto",year #return year #print year, month, day, hr, 0, 0.0 return gpsFromUTC(year, month, day, hr, 0, 0.0)[0]
[docs] def julianDay(year, month, day): """Return day of year (1-366) for given date. Parameters ---------- year, month, day : int Date components. Returns ------- int Day since Jan 1 of year. """ hr = 12 #make sure you fall into right day, middle is save t = time.mktime((year, month, day, hr, 0, 0.0, 0, 0, -1)) julDay = time.localtime(t)[7] return julDay
[docs] def mkUTC(year, month, day, hour, minute, sec): """Convert UTC date/time to seconds since epoch (like mktime but for UTC). Parameters ---------- year, month, day, hour, minute, sec : int or float UTC components. Returns ------- float Seconds since epoch. """ spec = [year, month, day, hour, minute, sec] + [0, 0, 0] utc = time.mktime(spec) - time.timezone return utc
[docs] def ymdhmsFromPyUTC(pyUTC): """Return (year, month, day, hour, minute, sec) from Python UTC time. Parameters ---------- pyUTC : float Seconds since epoch (e.g. from time.time()). Returns ------- tuple (year, month, day, hour, minute, sec). """ ymdhmsXXX = time.gmtime(pyUTC) return ymdhmsXXX[:-3]
[docs] def wtFromUTCpy(pyUTC, leapSecs=14): """Convert Python UTC time to GPS week and time of week. Parameters ---------- pyUTC : float Seconds since epoch (UTC). leapSecs : int, optional Leap seconds offset. Default is 14. Returns ------- tuple (gpsWeek, secsOfWeek). """ ymdhms = ymdhmsFromPyUTC(pyUTC) wSowDSoD = gpsFromUTC(*ymdhms + (leapSecs,)) return wSowDSoD[0:2]
[docs] def gpsFromUTC(year, month, day, hour, minute, ssec, leapSecs=30): """Convert UTC to GPS week, seconds of week, GPS day, seconds of day. Parameters ---------- year, month, day, hour, minute : int UTC date/time components. ssec : float Seconds (and fraction). leapSecs : int, optional Leap seconds (GPS - UTC). Default is 30; update as leap seconds change. Returns ------- tuple (gpsWeek, secsOfWeek, gpsDay, secsOfDay). Notes ----- GPS time is seconds since 1980-01-06 00:00:00. Week starts Saturday midnight. See http://www.oc.nps.navy.mil/~jclynch/timsys.html. Python uses integer seconds; fractional seconds in ssec are preserved in the return value. """ secFract = ssec % 1 sec=int(math.floor(ssec)) epochTuple = gpsEpoch + (-1, -1, 0) t0 = time.mktime(epochTuple) t = time.mktime((year, month, day, hour, minute, sec, -1, -1, 0)) # Note: time.mktime strictly works in localtime and to yield UTC, it should be # corrected with time.timezone # However, since we use the difference, this correction is unnecessary. # Warning: trouble if daylight savings flag is set to -1 or 1 !!! t = t + leapSecs tdiff = t - t0 gpsSOW = (tdiff % secsInWeek) + secFract gpsWeek = int(math.floor(tdiff/secsInWeek)) gpsDay = int(math.floor(gpsSOW/secsInDay)) gpsSOD = (gpsSOW % secsInDay) return (gpsWeek, gpsSOW, gpsDay, gpsSOD)
[docs] def UTCFromGps(gpsWeek, SOW, leapSecs=14): """Convert GPS week and seconds of week to UTC. Parameters ---------- gpsWeek : int Full GPS week number (not modulo 1024). SOW : float Seconds of week. leapSecs : int, optional Leap seconds (GPS - UTC). Default is 14. Returns ------- tuple (year, month, day, hour, minute, sec). """ secFract = SOW % 1 epochTuple = gpsEpoch + (-1, -1, 0) t0 = time.mktime(epochTuple) - time.timezone #mktime is localtime, correct for UTC tdiff = (gpsWeek * secsInWeek) + SOW - leapSecs t = t0 + tdiff (year, month, day, hh, mm, ss, dayOfWeek, julianDay, _daylightsaving) = time.gmtime(t) #use gmtime since localtime does not allow to switch off daylighsavings correction!!! return (year, month, day, hh, mm, ss + secFract)
[docs] def GpsSecondsFromPyUTC(pyUTC, _leapSecs=14): """Convert Python epoch time to GPS seconds (since GPS epoch). Parameters ---------- pyUTC : float Seconds since Python epoch (e.g. time.time()). _leapSecs : int, optional Unused; kept for API compatibility. Returns ------- int GPS seconds since 1980-01-06 00:00:00. """ t = gpsFromUTC(*ymdhmsFromPyUTC( pyUTC )) return int(t[0] * 60 * 60 * 24 * 7 + t[1])
#def PyUTCFromGpsSeconds(gpsseconds): # """converts gps seconds to the # python epoch. That is, the time # that would be returned from time.time() # at gpsseconds. # """ # pyUTC #===== Tests =========================================
[docs] def testTimeStuff(): print("-"*20) print() print("The GPS Epoch when everything began (1980, 1, 6, 0, 0, 0, leapSecs=0)") (w, sow, d, sod) = gpsFromUTC(1980, 1, 6, 0, 0, 0, leapSecs=0) print("**** week: %s, sow: %s, day: %s, sod: %s" % (w, sow, d, sod)) print(" and hopefully back:") print("**** %s, %s, %s, %s, %s, %s\n" % UTCFromGps(w, sow, leapSecs=0)) print("The time of first Rollover of GPS week (1999, 8, 21, 23, 59, 47)") (w, sow, d, sod) = gpsFromUTC(1999, 8, 21, 23, 59, 47) print("**** week: %s, sow: %s, day: %s, sod: %s" % (w, sow, d, sod)) print(" and hopefully back:") print("**** %s, %s, %s, %s, %s, %s\n" % UTCFromGps(w, sow, leapSecs=14)) print("Today is GPS week 1186, day 3, seems to run ok (2002, 10, 2, 12, 6, 13.56)") (w, sow, d, sod) = gpsFromUTC(2002, 10, 2, 12, 6, 13.56) print("**** week: %s, sow: %s, day: %s, sod: %s" % (w, sow, d, sod)) print(" and hopefully back:") print("**** %s, %s, %s, %s, %s, %s\n" % UTCFromGps(w, sow))
[docs] def testJulD(): print('2002, 10, 11 -> 284 ==??== ', julianDay(2002, 10, 11))
[docs] def testGpsWeek(): print('2002, 10, 11 -> 1187 ==??== ', gpsWeek(2002, 10, 11))
[docs] def testDayOfWeek(): print('2002, 10, 12 -> 6 ==??== ', dayOfWeek(2002, 10, 12)) print('2002, 10, 6 -> 0 ==??== ', dayOfWeek(2002, 10, 6))
[docs] def testPyUtilties(): ymdhms = (2002, 10, 12, 8, 34, 12.3) print("testing for: ", ymdhms) pyUtc = mkUTC(*ymdhms) back = ymdhmsFromPyUTC(pyUtc) print("yields : ", back) #*********************** !!!!!!!! #assert(ymdhms == back) #! TODO: this works only with int seconds!!! fix!!! (w, t) = wtFromUTCpy(pyUtc) print("week and time: ", (w,t))
#===== Main ========================================= if __name__ == "__main__": pass testTimeStuff() testGpsWeek() testJulD() testDayOfWeek() testPyUtilties()