Package glue :: Module gpstime
[hide private]
[frames] | no frames]

Source Code for Module glue.gpstime

  1  """ 
  2  A Python implementation of GPS related time conversions. 
  3   
  4  Copyright 2002 by Bud P. Bruegger, Sistema, Italy 
  5  mailto:bud@sistema.it 
  6  http://www.sistema.it 
  7   
  8  Modifications for GPS seconds by Duncan Brown 
  9   
 10  PyUTCFromGpsSeconds added by Ben Johnson 
 11   
 12  This program is free software; you can redistribute it and/or modify it under 
 13  the terms of the GNU Lesser General Public License as published by the Free 
 14  Software Foundation; either version 2 of the License, or (at your option) any 
 15  later version. 
 16   
 17  This program is distributed in the hope that it will be useful, but WITHOUT ANY 
 18  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
 19  PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
 20  details. 
 21   
 22  You should have received a copy of the GNU Lesser General Public License along 
 23  with this program; if not, write to the Free Software Foundation, Inc., 59 
 24  Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 25   
 26  GPS Time Utility functions 
 27   
 28  This file contains a Python implementation of GPS related time conversions. 
 29   
 30  The two main functions convert between UTC and GPS time (GPS-week, time of 
 31  week in seconds, GPS-day, time of day in seconds).  The other functions are 
 32  convenience wrappers around these base functions.   
 33   
 34  A good reference for GPS time issues is: 
 35  http://www.oc.nps.navy.mil/~jclynch/timsys.html 
 36   
 37  Note that python time types are represented in seconds since (a platform 
 38  dependent Python) Epoch.  This makes implementation quite straight forward 
 39  as compared to some algorigthms found in the literature and on the web.   
 40  """ 
 41   
 42  from __future__ import print_function 
 43  __author__ = 'Duncan Brown <duncan@gravity.phys.uwm.edu>' 
 44  from glue import git_version 
 45  __date__ = git_version.date 
 46  __version__ = git_version.id 
 47   
 48  import time, math 
 49   
 50  secsInWeek = 604800 
 51  secsInDay = 86400 
 52  gpsEpoch = (1980, 1, 6, 0, 0, 0)  # (year, month, day, hh, mm, ss) 
 53   
54 -def dayOfWeek(year, month, day):
55 "returns day of week: 0=Sun, 1=Mon, .., 6=Sat" 56 hr = 12 #make sure you fall into right day, middle is save 57 t = time.mktime((year, month, day, hr, 0, 0.0, 0, 0, -1)) 58 pyDow = time.localtime(t)[6] 59 gpsDow = (pyDow + 1) % 7 60 return gpsDow
61
62 -def gpsWeek(year, month, day):
63 "returns (full) gpsWeek for given date (in UTC)" 64 hr = 12 #make sure you fall into right day, middle is save 65 return gpsFromUTC(year, month, day, hr, 0, 0.0)[0]
66 67
68 -def julianDay(year, month, day):
69 "returns julian day=day since Jan 1 of year" 70 hr = 12 #make sure you fall into right day, middle is save 71 t = time.mktime((year, month, day, hr, 0, 0.0, 0, 0, -1)) 72 julDay = time.localtime(t)[7] 73 return julDay
74
75 -def mkUTC(year, month, day, hour, min, sec):
76 "similar to python's mktime but for utc" 77 spec = [year, month, day, hour, min, sec] + [0, 0, 0] 78 utc = time.mktime(spec) - time.timezone 79 return utc
80
81 -def ymdhmsFromPyUTC(pyUTC):
82 "returns tuple from a python time value in UTC" 83 ymdhmsXXX = time.gmtime(pyUTC) 84 return ymdhmsXXX[:-3]
85
86 -def wtFromUTCpy(pyUTC, leapSecs=14):
87 """convenience function: 88 allows to use python UTC times and 89 returns only week and tow""" 90 ymdhms = ymdhmsFromPyUTC(pyUTC) 91 wSowDSoD = gpsFromUTC(*ymdhms + (leapSecs,)) 92 return wSowDSoD[0:2]
93
94 -def gpsFromUTC(year, month, day, hour, min, sec, leapSecs=14):
95 """converts UTC to: gpsWeek, secsOfWeek, gpsDay, secsOfDay 96 97 a good reference is: http://www.oc.nps.navy.mil/~jclynch/timsys.html 98 99 This is based on the following facts (see reference above): 100 101 GPS time is basically measured in (atomic) seconds since 102 January 6, 1980, 00:00:00.0 (the GPS Epoch) 103 104 The GPS week starts on Saturday midnight (Sunday morning), and runs 105 for 604800 seconds. 106 107 Currently, GPS time is 13 seconds ahead of UTC (see above reference). 108 While GPS SVs transmit this difference and the date when another leap 109 second takes effect, the use of leap seconds cannot be predicted. This 110 routine is precise until the next leap second is introduced and has to be 111 updated after that. 112 113 SOW = Seconds of Week 114 SOD = Seconds of Day 115 116 Note: Python represents time in integer seconds, fractions are lost!!! 117 """ 118 secFract = sec % 1 119 epochTuple = gpsEpoch + (-1, -1, 0) 120 t0 = time.mktime(epochTuple) 121 t = time.mktime((year, month, day, hour, min, sec, -1, -1, 0)) 122 # Note: time.mktime strictly works in localtime and to yield UTC, it should be 123 # corrected with time.timezone 124 # However, since we use the difference, this correction is unnecessary. 125 # Warning: trouble if daylight savings flag is set to -1 or 1 !!! 126 t = t + leapSecs 127 tdiff = t - t0 128 gpsSOW = (tdiff % secsInWeek) + secFract 129 gpsWeek = int(math.floor(tdiff/secsInWeek)) 130 gpsDay = int(math.floor(gpsSOW/secsInDay)) 131 gpsSOD = (gpsSOW % secsInDay) 132 return (gpsWeek, gpsSOW, gpsDay, gpsSOD)
133 134
135 -def UTCFromGps(gpsWeek, SOW, leapSecs=14):
136 """converts gps week and seconds to UTC 137 138 see comments of inverse function! 139 140 SOW = seconds of week 141 gpsWeek is the full number (not modulo 1024) 142 """ 143 secFract = SOW % 1 144 epochTuple = gpsEpoch + (-1, -1, 0) 145 t0 = time.mktime(epochTuple) - time.timezone #mktime is localtime, correct for UTC 146 tdiff = (gpsWeek * secsInWeek) + SOW - leapSecs 147 t = t0 + tdiff 148 (year, month, day, hh, mm, ss, dayOfWeek, julianDay, daylightsaving) = time.gmtime(t) 149 #use gmtime since localtime does not allow to switch off daylighsavings correction!!! 150 return (year, month, day, hh, mm, ss + secFract)
151
152 -def GpsSecondsFromPyUTC( pyUTC, leapSecs=14 ):
153 """converts the python epoch to gps seconds 154 155 pyEpoch = the python epoch from time.time() 156 """ 157 t = t=gpsFromUTC(*ymdhmsFromPyUTC( pyUTC )) 158 return int(t[0] * 60 * 60 * 24 * 7 + t[1])
159
160 -def PyUTCFromGpsSeconds(gpsseconds):
161 """converts gps seconds to the 162 python epoch. That is, the time 163 that would be returned from time.time() 164 at gpsseconds. 165 """ 166 pyUTC
167 168 #===== Tests ========================================= 169
170 -def testTimeStuff():
171 print("-"*20) 172 print() 173 print("The GPS Epoch when everything began (1980, 1, 6, 0, 0, 0, leapSecs=0)") 174 (w, sow, d, sod) = gpsFromUTC(1980, 1, 6, 0, 0, 0, leapSecs=0) 175 print("**** week: %s, sow: %s, day: %s, sod: %s" % (w, sow, d, sod)) 176 print(" and hopefully back:") 177 print("**** %s, %s, %s, %s, %s, %s\n" % UTCFromGps(w, sow, leapSecs=0)) 178 179 print("The time of first Rollover of GPS week (1999, 8, 21, 23, 59, 47)") 180 (w, sow, d, sod) = gpsFromUTC(1999, 8, 21, 23, 59, 47) 181 print("**** week: %s, sow: %s, day: %s, sod: %s" % (w, sow, d, sod)) 182 print(" and hopefully back:") 183 print("**** %s, %s, %s, %s, %s, %s\n" % UTCFromGps(w, sow, leapSecs=14)) 184 185 print("Today is GPS week 1186, day 3, seems to run ok (2002, 10, 2, 12, 6, 13.56)") 186 (w, sow, d, sod) = gpsFromUTC(2002, 10, 2, 12, 6, 13.56) 187 print("**** week: %s, sow: %s, day: %s, sod: %s" % (w, sow, d, sod)) 188 print(" and hopefully back:") 189 print("**** %s, %s, %s, %s, %s, %s\n" % UTCFromGps(w, sow))
190
191 -def testJulD():
192 print('2002, 10, 11 -> 284 ==??== ', julianDay(2002, 10, 11))
193
194 -def testGpsWeek():
195 print('2002, 10, 11 -> 1187 ==??== ', gpsWeek(2002, 10, 11))
196
197 -def testDayOfWeek():
198 print('2002, 10, 12 -> 6 ==??== ', dayOfWeek(2002, 10, 12)) 199 print('2002, 10, 6 -> 0 ==??== ', dayOfWeek(2002, 10, 6))
200
201 -def testPyUtilties():
202 ymdhms = (2002, 10, 12, 8, 34, 12.3) 203 print("testing for: ", ymdhms) 204 pyUtc = mkUTC(*ymdhms) 205 back = ymdhmsFromPyUTC(pyUtc) 206 print("yields : ", back) 207 #*********************** !!!!!!!! 208 #assert(ymdhms == back) 209 #! TODO: this works only with int seconds!!! fix!!! 210 (w, t) = wtFromUTCpy(pyUtc) 211 print("week and time: ", (w,t))
212 213 214 #===== Main ========================================= 215 if __name__ == "__main__": 216 pass 217 testTimeStuff() 218 testGpsWeek() 219 testJulD() 220 testDayOfWeek() 221 testPyUtilties() 222