1- """Timing conversions between reference frames.
1+ """Timing conversions between reference frames for times .
22
33Frame options are described in detail at on the documentation website:
4- https://gnss-lib-py.readthedocs.io/en/latest/reference/reference.html#standard-naming -conventions
4+ https://gnss-lib-py.readthedocs.io/en/latest/reference/reference.html#timing -conventions
55
66Frame options include:
77 - gps_millis : GPS milliseconds
@@ -78,24 +78,19 @@ def get_leap_seconds(gps_time):
7878 return out_leapsecs
7979
8080
81- def gps_millis_to_tow (millis , add_leap_secs = False , verbose = False ):
81+ def gps_millis_to_tow (millis ):
8282 """Convert milliseconds since GPS epoch to GPS week number and time.
8383
8484 The initial GPS epoch is defined by the variable GPS_EPOCH_0 at
8585 which the week number is assumed to be 0.
8686
87+ Both of these times are in the GPS time frame of reference and as a
88+ result, leap seconds do not need to be accounted for here.
89+
8790 Parameters
8891 ----------
8992 millis : float or array-like of floats
9093 Float object for Time of Clock [ms].
91- add_leap_secs : bool
92- Flag for whether input is in UTC seconds or GPS seconds.
93- If True, we assume that input millis do not contain leap seconds
94- and add them to the output time.
95- If False, we assume that input millis contain leap seconds and
96- do not add them.
97- verbose : bool
98- Flag for whether to print that leapseconds were added.
9994
10095 Returns
10196 -------
@@ -120,11 +115,6 @@ def gps_millis_to_tow(millis, add_leap_secs=False, verbose=False):
120115 for milli in millis :
121116 gps_week , tow = divmod (milli , 7 * 86400 * 1000 )
122117 tow = tow / 1000.0
123- if add_leap_secs :
124- out_leapsecs = get_leap_seconds (milli )
125- if verbose : #pragma: no cover
126- print ('Leap seconds added' )
127- tow = tow + out_leapsecs
128118
129119 gps_weeks .append (np .int64 (gps_week ))
130120 tows .append (tow )
@@ -134,19 +124,17 @@ def gps_millis_to_tow(millis, add_leap_secs=False, verbose=False):
134124 return gps_weeks , tows
135125
136126
137- def datetime_to_tow (t_datetimes , add_leap_secs = True , verbose = False ):
127+ def datetime_to_tow (t_datetimes ):
138128 """Convert Python datetime object to GPS Week and time of week.
139129
130+ For the `gnss_lib_py` convention, except for specific applications,
131+ we assume that the time recorded by the `datetime.datetime` object
132+ is UTC time. As a result, on converting to TOW, we add leap seconds.
133+
140134 Parameters
141135 ----------
142136 t_datetimes : datetime.datetime or array-like of datetime.datetime
143- Datetime object for Time of Clock.
144- add_leap_secs : bool
145- Flag for whether output is in UTC seconds or GPS seconds.
146- If True, the output is in the GPS timing frame of reference and
147- leap seconds are added.
148- If False, the output is in the UTC timing frame of reference and
149- leap seconds are not added.
137+ Datetime object for Time of Clock, assumed to be in UTC time frame.
150138 verbose : bool
151139 Flag for whether to print that leapseconds were added.
152140
@@ -173,11 +161,8 @@ def datetime_to_tow(t_datetimes, add_leap_secs=True, verbose=False):
173161 if t_datetime < GPS_EPOCH_0 :
174162 raise RuntimeError ("Input time must be after GPS epoch " \
175163 + str (GPS_EPOCH_0 ))
176- if add_leap_secs :
177- out_leapsecs = get_leap_seconds (t_datetime )
178- t_datetime = t_datetime + timedelta (seconds = out_leapsecs )
179- if verbose : # pragma: no cover
180- print ("Leap seconds added" )
164+ out_leapsecs = get_leap_seconds (t_datetime )
165+ t_datetime = t_datetime + timedelta (seconds = out_leapsecs )
181166 gps_week = (t_datetime - GPS_EPOCH_0 ).days // 7
182167
183168 tow = ((t_datetime - GPS_EPOCH_0 ) - timedelta (gps_week * 7.0 )).total_seconds ()
@@ -190,17 +175,18 @@ def datetime_to_tow(t_datetimes, add_leap_secs=True, verbose=False):
190175 return gps_weeks , tows
191176
192177
193- def tow_to_datetime (gps_weeks , tows , rem_leap_secs = True ):
178+ def tow_to_datetime (gps_weeks , tows ):
194179 """Convert GPS week and time of week (seconds) to datetime.
195180
181+ Because we assume that `datetime.datetime` objects are in UTC time,
182+ leap seconds are removed from the given TOW.
183+
196184 Parameters
197185 ----------
198186 gps_weeks : int or array-like of ints
199187 GPS week.
200188 tows : float or array-like of floats
201189 GPS time of week [s].
202- rem_leap_secs : bool
203- Flag on whether to remove leap seconds from given tow.
204190
205191 Returns
206192 -------
@@ -231,9 +217,8 @@ def tow_to_datetime(gps_weeks, tows, rem_leap_secs=True):
231217
232218 seconds_since_epoch = WEEKSEC * gps_week + tow
233219 t_datetime = GPS_EPOCH_0 + timedelta (seconds = seconds_since_epoch )
234- if rem_leap_secs :
235- leap_secs = get_leap_seconds (t_datetime )
236- t_datetime = t_datetime - timedelta (seconds = leap_secs )
220+ leap_secs = get_leap_seconds (t_datetime )
221+ t_datetime = t_datetime - timedelta (seconds = leap_secs )
237222
238223 t_datetimes .append (t_datetime )
239224
@@ -249,8 +234,8 @@ def tow_to_unix_millis(gps_weeks, tows):
249234
250235 Convert GPS week and time of week (seconds) to milliseconds since
251236 UNIX epoch.
252- Leap seconds will always be removed from tow because of offset between
253- UTC and GPS clocks .
237+ Leap seconds will always be removed from tow because GPS millis is a
238+ continuous time reference while unix millis adjust for leap seconds .
254239
255240 Parameters
256241 ----------
@@ -287,7 +272,7 @@ def tow_to_unix_millis(gps_weeks, tows):
287272 for t_idx , gps_week in enumerate (gps_weeks ):
288273 tow = tows [t_idx ]
289274
290- t_utc = tow_to_datetime (gps_week , tow , rem_leap_secs = True )
275+ t_utc = tow_to_datetime (gps_week , tow )
291276 t_utc = t_utc .replace (tzinfo = timezone .utc )
292277 unix_milli = datetime_to_unix_millis (t_utc )
293278 unix_millis .append (unix_milli )
@@ -329,7 +314,8 @@ def tow_to_gps_millis(gps_week, tow):
329314def datetime_to_unix_millis (t_datetimes ):
330315 """Convert datetime to milliseconds since UNIX Epoch (1/1/1970 UTC).
331316
332- If no timezone is specified, assumes UTC as timezone.
317+ If no timezone is specified, assumes UTC as timezone. This function
318+ does not add leapseconds to the datetime to get unix millis.
333319
334320 Parameters
335321 ----------
@@ -363,20 +349,19 @@ def datetime_to_unix_millis(t_datetimes):
363349 return unix_millis_list
364350
365351
366- def datetime_to_gps_millis (t_datetimes , add_leap_secs = True ):
352+ def datetime_to_gps_millis (t_datetimes ):
367353 """Convert datetime to milliseconds since GPS Epoch.
368354
369355 GPS Epoch starts at the 6th January 1980.
370356 If no timezone is specified, assumes UTC as timezone and returns
371357 milliseconds in GPS time frame of reference by adding leap seconds.
372- Milliseconds are not added when the flag add_leap_secs is False.
358+ Leap seconds are always added because UTC time is adjusted for leap
359+ seconds while GPS milliseconds are not.
373360
374361 Parameters
375362 ----------
376363 t_datetime : datetime.datetime or array-like of datetime.datetime
377364 UTC time as a datetime object.
378- add_leap_secs : bool
379- Flag for whether output is in UTC seconds or GPS seconds.
380365
381366 Returns
382367 -------
@@ -386,7 +371,7 @@ def datetime_to_gps_millis(t_datetimes, add_leap_secs=True):
386371
387372
388373 """
389- gps_weeks , tows = datetime_to_tow (t_datetimes , add_leap_secs = add_leap_secs )
374+ gps_weeks , tows = datetime_to_tow (t_datetimes )
390375 gps_millis = tow_to_gps_millis (gps_weeks , tows )
391376 return gps_millis
392377
@@ -448,11 +433,11 @@ def unix_millis_to_tow(unix_millis):
448433 """
449434
450435 t_utc = unix_millis_to_datetime (unix_millis )
451- gps_week , tow = datetime_to_tow (t_utc , add_leap_secs = True )
436+ gps_week , tow = datetime_to_tow (t_utc )
452437 return np .int64 (gps_week ), tow
453438
454439
455- def unix_to_gps_millis (unix_millis , add_leap_secs = True ):
440+ def unix_to_gps_millis (unix_millis ):
456441 """Convert milliseconds since UNIX epoch (1/1/1970) to GPS millis.
457442
458443 Adds leap seconds by default but time can be kept in UTC frame by
@@ -477,21 +462,24 @@ def unix_to_gps_millis(unix_millis, add_leap_secs=True):
477462 gps_millis = np .zeros_like (unix_millis )
478463 for t_idx , unix in enumerate (unix_millis ):
479464 t_utc = unix_millis_to_datetime (unix )
480- gps_millis [t_idx ] = datetime_to_gps_millis (t_utc , add_leap_secs = add_leap_secs )
465+ gps_millis [t_idx ] = datetime_to_gps_millis (t_utc )
481466 gps_millis = gps_millis .astype (np .float64 )
482467 else :
483468 t_utc = unix_millis_to_datetime (unix_millis )
484- gps_millis = np .float64 (datetime_to_gps_millis (t_utc , add_leap_secs = add_leap_secs ))
469+ gps_millis = np .float64 (datetime_to_gps_millis (t_utc ))
485470 return gps_millis
486471
487472
488- def gps_millis_to_datetime (gps_millis , rem_leap_secs = True ):
473+ def gps_millis_to_datetime (gps_millis ):
489474 """Convert milliseconds since GPS epoch to datetime.
490475
491476 GPS millis is from the start of the GPS in GPS reference.
492477 The initial GPS epoch is defined by the variable GPS_EPOCH_0 at
493478 which the week number is assumed to be 0.
494479
480+ The :code:`datetime` instances are assumed to be in UTC time and leap
481+ seconds are removed from the gps_millis as a result.
482+
495483 Parameters
496484 ----------
497485 gps_millis : float or array-like of float
@@ -505,18 +493,21 @@ def gps_millis_to_datetime(gps_millis, rem_leap_secs=True):
505493 UTC time as a datetime object. Either `datetime.datetime` or
506494 `np.ndarray` with `dtype = datetime.datetime`.
507495 """
508- gps_week , tow = gps_millis_to_tow (gps_millis , add_leap_secs = False )
509- t_utc = tow_to_datetime (gps_week , tow , rem_leap_secs = rem_leap_secs )
496+ gps_week , tow = gps_millis_to_tow (gps_millis )
497+ t_utc = tow_to_datetime (gps_week , tow )
510498 return t_utc
511499
512500
513- def gps_to_unix_millis (gps_millis , rem_leap_secs = True ):
501+ def gps_to_unix_millis (gps_millis ):
514502 """Convert milliseconds since GPS epoch to UNIX millis.
515503
516504 GPS millis is from the start of the GPS in GPS reference.
517505 The initial GPS epoch is defined by the variable GPS_EPOCH_0 at
518506 which the week number is assumed to be 0.
519507
508+ Leap seconds are removed from gps_millis because of the difference
509+ between how GPS and Unix time handle milliseconds.
510+
520511 Parameters
521512 ----------
522513 gps_millis : float or array-like of float
@@ -537,15 +528,49 @@ def gps_to_unix_millis(gps_millis, rem_leap_secs=True):
537528 and len (np .atleast_1d (gps_millis )) > 1 :
538529 unix_millis = np .zeros_like (gps_millis )
539530 for t_idx , gps in enumerate (gps_millis ):
540- t_utc = gps_millis_to_datetime (gps , rem_leap_secs = rem_leap_secs )
531+ t_utc = gps_millis_to_datetime (gps )
541532 unix_millis [t_idx ] = datetime_to_unix_millis (t_utc )
542533 gps_millis = gps_millis .astype (np .float64 )
543534 else :
544- t_utc = gps_millis_to_datetime (gps_millis , rem_leap_secs = rem_leap_secs )
535+ t_utc = gps_millis_to_datetime (gps_millis )
545536 unix_millis = np .float64 (datetime_to_unix_millis (t_utc ))
546537 return unix_millis
547538
548539
540+ def gps_datetime_to_gps_millis (t_gps ):
541+ """Convert datetime in GPS time of reference to milliseconds since GPS Epoch.
542+
543+ GPS Epoch starts at the 6th January 1980.
544+ This function assumes that the input datetime is in the GPS time
545+ frame of reference and converts that to GPS milliseconds.
546+
547+ Parameters
548+ ----------
549+ t_datetime : datetime.datetime or array-like of datetime.datetime
550+ GPS time as a datetime object.
551+
552+ Returns
553+ -------
554+ gps_millis : float or np.ndarray
555+ Milliseconds since GPS Epoch (6th January 1980 GPS). Either
556+ `float` or `np.ndarray` with `dtype = float`.
557+
558+
559+ """
560+ if isinstance (t_gps ,datetime ):
561+ t_gps = [t_gps ]
562+ if isinstance (t_gps ,np .ndarray ) \
563+ and len (np .atleast_1d (t_gps )) == 1 :
564+ t_gps = [t_gps .item ()]
565+ gps_millis = []
566+ for t_datetime in t_gps :
567+ gps_milli = (t_datetime - GPS_EPOCH_0 ).total_seconds ()* 1000
568+ gps_millis .append (gps_milli )
569+ gps_millis = np .squeeze (np .asarray (gps_millis ))
570+ return gps_millis
571+
572+
573+
549574def tzinfo_to_utc (t_datetime ):
550575 """Raises warning if time doesn't have timezone and converts to UTC.
551576
0 commit comments