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)
53
55 "returns day of week: 0=Sun, 1=Mon, .., 6=Sat"
56 hr = 12
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
63 "returns (full) gpsWeek for given date (in UTC)"
64 hr = 12
65 return gpsFromUTC(year, month, day, hr, 0, 0.0)[0]
66
67
69 "returns julian day=day since Jan 1 of year"
70 hr = 12
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
82 "returns tuple from a python time value in UTC"
83 ymdhmsXXX = time.gmtime(pyUTC)
84 return ymdhmsXXX[:-3]
85
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
123
124
125
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
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
146 tdiff = (gpsWeek * secsInWeek) + SOW - leapSecs
147 t = t0 + tdiff
148 (year, month, day, hh, mm, ss, dayOfWeek, julianDay, daylightsaving) = time.gmtime(t)
149
150 return (year, month, day, hh, mm, ss + secFract)
151
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
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
169
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
192 print('2002, 10, 11 -> 284 ==??== ', julianDay(2002, 10, 11))
193
195 print('2002, 10, 11 -> 1187 ==??== ', gpsWeek(2002, 10, 11))
196
198 print('2002, 10, 12 -> 6 ==??== ', dayOfWeek(2002, 10, 12))
199 print('2002, 10, 6 -> 0 ==??== ', dayOfWeek(2002, 10, 6))
200
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
209
210 (w, t) = wtFromUTCpy(pyUtc)
211 print("week and time: ", (w,t))
212
213
214
215 if __name__ == "__main__":
216 pass
217 testTimeStuff()
218 testGpsWeek()
219 testJulD()
220 testDayOfWeek()
221 testPyUtilties()
222