Skip to content

Core

Copyright 2020 The Aerospace Corporation

GPSTime

Time representation for GPS.

Parameters

week_number : int The number of weeks since the start of the GPS epoch, 6 Jan 1980. seconds : int The number of integer seconds into the week. The zero time is at midnight on Sunday morning, i.e. betwen Saturday and Sunday. Should be between 0 and 604800 because otherwise, the week number would be incorrect. femtoseconds : int The number of femtoseconds into the week. That is, this is the number of fractional seconds in the time of week with a scale factor of 1e15.

Source code in gps_time/core.py
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
class GPSTime:
    """Time representation for GPS.

    Parameters
    ----------
    week_number : int
        The number of weeks since the start of the GPS epoch, 6 Jan 1980.
    seconds : int
        The number of integer seconds into the week. The zero time is at
        midnight on Sunday morning, i.e. betwen Saturday and Sunday. Should
        be between 0 and 604800 because otherwise, the week number would be
        incorrect.
    femtoseconds : int
        The number of femtoseconds into the week. That is, this is the number
        of fractional seconds in the time of week with a scale factor of 1e15.
    """

    """
    Todo
    ----
    .. todo:: Create a GPSTimeDelta class to handle adding/subtracting with
        increase accuracy.

    """

    """
    Raises
    ------
    TypeError
        For various operators if not the selected types are not implemented.
    ValueError
        If an incorrect set of input arguments are provided to the constructor
    """

    weeks: int
    seconds: int
    femtoseconds: int

    yaml_tag: str = u"!GPSTime"

    def __init__(self, week_number: int, *args, **kwargs) -> None:
        """Object constructor.

        This sets the week number and the time of week and ensures that the
        time of week is a float. It also calls `correct_time()`, which checks
        to see if the time of week is negative or past the end of the week
        and adjust the values accordingly.

        This constructor supports many different input arguments. However some
        sets of input arguments may result in truncation and errors if a
        `float` is provided when an `int` is expected.

        Parameters
        ----------
        week_number : int
            The number of week
        *args, **kwargs
            The time of week in various representations. If positional arguments
            are used, a single positional argument is interpreted as a time of
            week (i.e. a float), while two arguments are interpreted as seconds
            and femtoseconds. In the latter case, the values will be cast as
            integers, which may result in truncation. Keyword arguments function
            in much the same way, with "time_of_week", "seconds", and
            "femtoseconds" being the valid keyword arguments. If only "seconds"
            is given, it will be treated like "time_of_week". If no additional
            arguments are given, the time is assumed to be the start of the week.
        """

        """
        Raises
        ------
        ValueError
            If invalid arguments are given. Examples include:
            - Mixed positional and keyword arguments are not supported
            - More than two arguments are not supported
            - Keyword arguments "time_of_week" and "femtoseconds" cannot be
              used together.

        """
        self.yaml_tag: str = u"!GPSTime"
        if len(args) > 0 and len(kwargs) > 0:
            raise ValueError(
                "GPSTime does not support both positional and keyword arguments."
            )

        self.week_number = int(week_number)
        if len(args) > 2:  # If more than 3 args (week + 2 times)
            raise ValueError(
                "Only up to three arguments allowed (Week number, seconds, "
                "and femtoseconds)"
            )
        elif len(args) == 2:
            if isinstance(args[0], float) or isinstance(args[1], float):
                logger.warning(
                    "Two times given, but at least one is a float. Decimal "
                    "values will be truncated"
                )
            self.seconds = int(args[0])
            self.femtoseconds = int(args[1])
        elif len(args) == 1:
            self.time_of_week = args[0]
        else:
            if len(kwargs) > 2:
                raise ValueError("Too many arguments")
            elif len(kwargs) == 0:
                logger.warning(
                    "No time of week information. Defaulting to start of week"
                )
                self.seconds = 0
                self.femtoseconds = 0

            elif "femtoseconds" in kwargs:
                if "time_of_week" in kwargs:
                    raise ValueError(
                        """Keyword arguments "time_of_week" and "femtoseconds"
                        are incompatible."""
                    )
                elif "seconds" in kwargs:
                    if isinstance(kwargs["seconds"], float) or isinstance(
                        kwargs["femtoseconds"], float
                    ):
                        logger.warning(
                            "Two times given, but at least one is a float. "
                            "Decimal values will be truncated"
                        )
                    self.seconds = int(kwargs["seconds"])
                    self.femtoseconds = int(kwargs["femtoseconds"])
                else:
                    raise ValueError(
                        """Keyword argument "femtoseconds" must be
                        accompanied by "seconds"."""
                    )
            elif "seconds" in kwargs:
                logger.warning(
                    "seconds given with no femtoseconds. Will be handled "
                    "as time of week"
                )
                self.time_of_week = float(kwargs["seconds"])
            elif "time_of_week" in kwargs:
                self.time_of_week = float(kwargs["time_of_week"])
            else:
                raise ValueError("Invalid Keyword arguments")

        self.correct_time()
        if self.week_number < 0:
            logger.warning("Week number is less than 0")

    @property
    def time_of_week(self) -> float:
        """The time of week as a float."""
        return float(self.seconds + self.femtoseconds * _FEMTO_SEC_TO_SEC)

    @time_of_week.setter
    def time_of_week(self, time_of_week: float) -> None:
        """A setter for the time of week.

        The method allows the seconds and femtoseconds to be updated using
        a single float.

        Paremeters
        ----------
        time_of_week : float
            The time of week as a float
        """
        sec, femtosec = _tow2sec(time_of_week)
        self.seconds = sec
        self.femtoseconds = femtosec

    @classmethod
    def from_yaml(
        cls: type, constructor: ruamel.yaml.Constructor, node: ruamel.yaml.MappingNode
    ) -> GPSTime:
        """YAML Constructor.

        This YAML constructor is used to load a GPSTime from a YAML file. It must be
        registered with the YAML loader. This is accomplished using
        ```python3
        import ruamel.yaml
        yaml = ruamel.yaml.YAML()
        yaml.register_class(GPSTime)
        ```

        This class method is primarily used to add a constructor to an instance of
        ruamel.yaml. Its functionality as a traditional classmethod is limited.

        .. note:: YAML Module
            This constructor is meant to be used with ruamel.yaml. It has not been tested
            with pyyaml (the more common YAML library.)

        """
        nodes = node.value
        week_number = None
        seconds = None
        femtoseconds = None
        time_of_week = None
        for i in range(0, len(nodes)):
            node_name = nodes[i][0].value
            if node_name == "week_number":
                week_number = constructor.construct_scalar(nodes[i][1])
            elif node_name == "seconds":
                seconds = constructor.construct_scalar(nodes[i][1])
            elif node_name == "femtoseconds":
                femtoseconds = constructor.construct_scalar(nodes[i][1])
            elif node_name == "time_of_week":
                time_of_week = constructor.construct_scalar(nodes[i][1])

        if seconds is None and time_of_week is None:
            raise ValueError("The YAML file lacked both a time_of_week and a seconds")
        if seconds is not None and time_of_week is not None:
            raise ValueError(
                "YAML file defines both time_of_week and seconds (incompatible)"
            )
        elif time_of_week is not None and femtoseconds is not None:
            raise ValueError(
                "YAML file defines both time_of_week and femtoseconds (incompatible)"
            )
        elif seconds is not None and femtoseconds is None:
            seconds, femtoseconds = _tow2sec(float(seconds))
        elif time_of_week is not None:
            seconds, femtoseconds = _tow2sec(float(time_of_week))

        return cls(int(week_number), int(seconds), int(femtoseconds))

    def to_datetime(self) -> datetime.datetime:
        """Convert the `GPSTime` to a datetime.

        This method calls `tow2datetime()` to convert the `GPSTime` to a
        datetime object.

        Returns
        -------
        datetime.datetime
            The equivalent datetime representation of the `GPSTime`

        Notes
        -----
        .. note::
            Datetimes are limited to microsecond resolution, so this
            conversion may lose some fidelity.

        """
        return tow2datetime(self.week_number, self.time_of_week)

    @classmethod
    def from_datetime(cls, time: datetime.datetime) -> GPSTime:
        """Create a `GPSTime` for a datetime.

        Parameters
        ----------
        time : datetime.datetime
            The datetime that will be converted to a `GPSTime`

        Returns
        -------
        GPSTime
            The `GPSTime` corresponding to the datetime. This is a lossless
            conversion.
        """ 

        """
        Raises
        ------
        TypeError
            If the input value is not a datetime

        Notes
        -----
        This is a classmethod and thus can be called without instantiating the
        object first.

        """
        if not isinstance(time, datetime.datetime):
            raise TypeError("time must be a datetime")

        week_num, tow = datetime2tow(time)

        return cls(week_num, tow)

    def to_zcount(self) -> float:
        """Get the current Z-Count.

        Returns
        -------
        float
            The time of week divided by 1.5

        """
        return self.time_of_week / 1.5

    def correct_weeks(self) -> None:
        """Correct the week number based on the time of week.

        If the time of week is less than 0 or greater than 604800 seconds,
        then the week number and time of week will be corrected to ensure that
        the time of week is within the week indicated by the week number.

        Returns
        -------
        None

        """
        logger.warning(
            "The correct_weeks() method will be deprecated in a future version. Use the correct_time() method instead."
        )
        if (self.time_of_week >= _SEC_IN_WEEK) or (self.time_of_week < 0):
            weeks_to_add = int(self.time_of_week // _SEC_IN_WEEK)
            new_time_of_week = float(self.time_of_week % _SEC_IN_WEEK)

            self.week_number += weeks_to_add
            self.time_of_week = new_time_of_week
        else:
            pass

    def correct_time(self) -> None:
        if (self.femtoseconds >= _SEC_TO_FEMTO_SEC) or (self.femtoseconds < 0):
            seconds_to_add = int(self.femtoseconds // _SEC_TO_FEMTO_SEC)
            new_femto_sec = int(self.femtoseconds % _SEC_TO_FEMTO_SEC)

            self.seconds += seconds_to_add
            self.femtoseconds = new_femto_sec

        if (self.seconds >= _SEC_IN_WEEK) or (self.seconds < 0):
            weeks_to_add = int(self.seconds // _SEC_IN_WEEK)
            new_sec = int(self.seconds % _SEC_IN_WEEK)

            self.week_number += weeks_to_add
            self.seconds = new_sec

    def __add__(
        self,
        other: Union[
            int, float, GPSTime, datetime.datetime, datetime.timedelta, np.ndarray
        ],
    ) -> Union[GPSTime, np.ndarray]:
        """Addition, apply an offset to a `GPSTime`.

        This is the addition of a `GPSTime` and another object. In this
        context, addition means moving the clock of the first argument
        forward by some amount.

        Suppose `a` is a `GPSTime` and the value give for other represents a
        positive time. The value returned will be a `GPSTime` object that is
        the amount of time represented by other after `a`.

        Parameters
        ----------
        other : Union[int, float, GPSTime, datetime.datetime,
                      datetime.timedelta, np.ndarray]
            The other value to add to the `GPSTime`. `int` and `float` values
            are the number of seconds to add to the `GPSTime`. `GPSTime` and
            `datetime.timedelta` have explicit unit definitions that are used.
             If the value is a datetime.datetime, it is converted to a GPSTime
             before adding.

        Returns
        -------
        Union[GPSTime, np.ndarray]
            The sum of the `GPSTime` and `other`. If other is an np.array,
            returns the sum for each element
        """

        """
        Raises
        ------
        TypeError
            If other is not a supported type

        Notes
        -----
        .. note::
            Apart from adding of `datetime.timedelta` objects, this
            functionality does not exist with datetimes.

        .. note::
            This function can be used to "add" a negative amount of time,
            which can yield different results than subtraction.

        """
        if isinstance(other, bool):
            raise TypeError(
                "unsupported operand type(s) for -: '{}' and '{}'".format(
                    type(self), type(other)
                )
            )
        if isinstance(other, int) or isinstance(other, float):
            gps_time_to_add = GPSTime(0, float(other))
        elif isinstance(other, datetime.timedelta):
            gps_time_to_add = GPSTime(0, other.total_seconds())
        elif isinstance(other, datetime.datetime):
            gps_time_to_add = GPSTime.from_datetime(other)
        elif isinstance(other, GPSTime):
            gps_time_to_add = other
        elif isinstance(other, np.ndarray):
            input = np.array([self])
            return input + other
        else:
            raise TypeError(
                "unsupported operand type(s) for +: '{}' and '{}'".format(
                    type(self), type(other)
                )
            )

        week_num = self.week_number + gps_time_to_add.week_number
        seconds = self.seconds + gps_time_to_add.seconds
        femtoseconds = self.femtoseconds + gps_time_to_add.femtoseconds
        return GPSTime(week_num, seconds, femtoseconds)

    def __sub__(
        self,
        other: Union[
            int, float, GPSTime, datetime.datetime, datetime.timedelta, np.ndarray
        ],
    ) -> Union[GPSTime, float, np.ndarray]:
        """Subtraction.

        This method is used to represent subtraction. Depending on the type of
        the arguments, it can be used to find the time offset by an amount or
        the number of seconds between two times.

        Parameters
        ----------
        other : Union[int, float, GPSTime, datetime.datetime,
                      datetime.timedelta, np.ndarray]
            The other value to subtract from the `GPSTime`. `int` and `float`
            values are the number of seconds to subtract from the `GPSTime`.
            `GPSTime` and `datetime.timedelta` have explicit unit definitions
            that are used. If the value is a datetime.datetime, it is
            converted to a GPSTime before subtracting.

        Returns
        -------
        Union[GPSTime, float, np.ndarray]
            A float will be return if both values are `GPSTime` objects that
            represents the number of seconds between the objects. A GPSTime
            will be returned otherwise and it represents offsetting the time
            backward by the amount given. If the input is an np.ndarray, then
            returns the operation for each element

            Notes
            -----
            Subtracting a non-`GPSTime` object is equivalent to adding the opposite
            of its value
        """

        """
        Raises
        ------
        TypeError
            If other is not a supported type


        """
        if isinstance(other, bool):
            raise TypeError(
                "unsupported operand type(s) for -: '{}' and '{}'".format(
                    type(self), type(other)
                )
            )
        if isinstance(other, int) or isinstance(other, float):
            sec_to_sub, femto_to_sub = _tow2sec(float(other))

            return GPSTime(
                self.week_number,
                self.seconds - sec_to_sub,
                self.femtoseconds - femto_to_sub,
            )

        elif isinstance(other, datetime.timedelta):
            sec_to_sub, femto_to_sub = _tow2sec(float(other.total_seconds()))

            return GPSTime(
                self.week_number,
                self.seconds - sec_to_sub,
                self.femtoseconds - femto_to_sub,
            )

        elif isinstance(other, datetime.datetime):
            other_gpstime = GPSTime.from_datetime(other)

            weeks_diff = self.week_number - other_gpstime.week_number
            sec_diff = self.seconds - other_gpstime.seconds
            femto_diff = self.femtoseconds - other_gpstime.femtoseconds

            return float(
                weeks_diff * _SEC_IN_WEEK + sec_diff + femto_diff * _FEMTO_SEC_TO_SEC
            )

        elif isinstance(other, GPSTime):
            weeks_diff = self.week_number - other.week_number
            sec_diff = self.seconds - other.seconds
            femto_diff = self.femtoseconds - other.femtoseconds

            return float(
                weeks_diff * _SEC_IN_WEEK + sec_diff + femto_diff * _FEMTO_SEC_TO_SEC
            )

        elif isinstance(other, np.ndarray):
            if other.dtype == object:
                _type = np.reshape(other, sum([i for i in other.shape]))[0].__class__

                if _type in (self.__class__, datetime.datetime):
                    input = np.array([self])
                    return np.array(input - other, dtype=float)
                elif _type is datetime.timedelta:
                    input = np.array([self])
                    return np.array(input - other, dtype=object)
            elif other.dtype in (
                int,
                float,
            ):
                input = np.array([self])
                return np.array(input - other, dtype=object)

        else:
            raise TypeError(
                "unsupported operand type(s) for -: '{}' and '{}'".format(
                    type(self), type(other)
                )
            )

    def __lt__(self, other: Union[GPSTime, datetime.datetime]) -> bool:
        """Comparison: Less Than.

        .. note:: In this context "less than" is equivalent to "before"

        Parameters
        ----------
        other : Union[GPSTime, datetime.datetime]
            The object to compare. Datatimes will be converted to `GPSTime`

        Returns
        -------
        bool
            True if the current object is before its comparison
        """

        """
        Raises
        ------
        TypeError
            If an invalid type

        """
        if isinstance(other, datetime.datetime):
            other_time = GPSTime.from_datetime(other)
        elif isinstance(other, GPSTime):
            other_time = other
        else:
            raise TypeError(
                "'<' not supported between instances of '{}' and '{}'".format(
                    type(self), type(other)
                )
            )
        return (self - other_time) < 0

    def __gt__(self, other: Union[GPSTime, datetime.datetime]) -> bool:
        """Comparison: Greater Than.

        .. note:: In this context "greater than" is equivalent to "after"

        Parameters
        ----------
        other : Union[GPSTime, datetime.datetime]
            The object to compare. Datatimes will be converted to `GPSTime`

        Returns
        -------
        bool
            True if the current object is after its comparison
        """

        """
        Raises
        ------
        TypeError
            If an invalid type

        """
        if isinstance(other, datetime.datetime):
            other_time = GPSTime.from_datetime(other)
        elif isinstance(other, GPSTime):
            other_time = other
        else:
            raise TypeError(
                "'>' not supported between instances of '{}' and '{}'".format(
                    type(self), type(other)
                )
            )
        return (self - other_time) > 0

    def __eq__(self, other: Union[GPSTime, datetime.datetime]) -> bool:
        """Comparison: Equality.

        .. note:: In this context "equality" is equivalent to "coincident"

        Parameters
        ----------
        other : Union[GPSTime, datetime.datetime]
            The object to compare. Datatimes will be converted to `GPSTime`

        Returns
        -------
        bool
            True if the current object is the same time as its comparison
        """

        """
        Raises
        ------
        TypeError
            If an invalid type

        """
        if isinstance(other, datetime.datetime):
            other_time = GPSTime.from_datetime(other)
        elif isinstance(other, GPSTime):
            other_time = other
        else:
            raise TypeError(
                "'>' not supported between instances of '{}' and '{}'".format(
                    type(self), type(other)
                )
            )
        return (self - other_time) == 0

    def __le__(self, other: Union[GPSTime, datetime.datetime]) -> bool:
        """Comparison: Less Than or Equals.

        Calls the `__lt__()` and `__eq__()` methods

        Parameters
        ----------
        other : Union[GPSTime, datetime.datetime]
            The object to compare. Datatimes will be converted to `GPSTime`

        Returns
        -------
        bool
            True if the current object is before or at the same time as its
            comparison object.
        """

        """
        Raises
        ------
        TypeError
            If an invalid type

        """
        return self.__lt__(other) or self.__eq__(other)

    def __ge__(self, other: Union[GPSTime, datetime.datetime]) -> bool:
        """Comparison: Greater Than or Equals.

        Calls the `__gt__()` and `__eq__()` methods

        Parameters
        ----------
        other : Union[GPSTime, datetime.datetime]
            The object to compare. Datatimes will be converted to `GPSTime`

        Returns
        -------
        bool
            True if the current object is after or at the same time as its
            comparison object.
        """

        """        
        Raises
        ------
        TypeError
            If an invalid type

        """
        return self.__gt__(other) or self.__eq__(other)

    def __ne__(self, other: Union[GPSTime, datetime.datetime]) -> bool:
        """Comparison: Not Equals.

        Inverts the result of the `__eq__()` method

        Parameters
        ----------
        other : Union[GPSTime, datetime.datetime]
            The object to compare. Datatimes will be converted to `GPSTime`

        Returns
        -------
        bool
            True if the current object is not the same time as its comparison
        """

        """
        Raises
        ------
        TypeError
            If an invalid type

        """
        return not (self.__eq__(other))

    def __hash__(self):
        """Make GPSTime hashable."""
        return hash(str(self.week_number) + str(self.seconds) + str(self.femtoseconds))

    def __repr__(self) -> str:
        """Representation of the object.

        Returns
        -------
        str
            The representation of the object

        """
        return "GPSTime(week_number={}, time_of_week={})".format(
            self.week_number, self.time_of_week
        )

time_of_week property writable

The time of week as a float.

__add__(other)

Addition, apply an offset to a GPSTime.

This is the addition of a GPSTime and another object. In this context, addition means moving the clock of the first argument forward by some amount.

Suppose a is a GPSTime and the value give for other represents a positive time. The value returned will be a GPSTime object that is the amount of time represented by other after a.

Parameters

other : Union[int, float, GPSTime, datetime.datetime, datetime.timedelta, np.ndarray] The other value to add to the GPSTime. int and float values are the number of seconds to add to the GPSTime. GPSTime and datetime.timedelta have explicit unit definitions that are used. If the value is a datetime.datetime, it is converted to a GPSTime before adding.

Returns

Union[GPSTime, np.ndarray] The sum of the GPSTime and other. If other is an np.array, returns the sum for each element

Source code in gps_time/core.py
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
def __add__(
    self,
    other: Union[
        int, float, GPSTime, datetime.datetime, datetime.timedelta, np.ndarray
    ],
) -> Union[GPSTime, np.ndarray]:
    """Addition, apply an offset to a `GPSTime`.

    This is the addition of a `GPSTime` and another object. In this
    context, addition means moving the clock of the first argument
    forward by some amount.

    Suppose `a` is a `GPSTime` and the value give for other represents a
    positive time. The value returned will be a `GPSTime` object that is
    the amount of time represented by other after `a`.

    Parameters
    ----------
    other : Union[int, float, GPSTime, datetime.datetime,
                  datetime.timedelta, np.ndarray]
        The other value to add to the `GPSTime`. `int` and `float` values
        are the number of seconds to add to the `GPSTime`. `GPSTime` and
        `datetime.timedelta` have explicit unit definitions that are used.
         If the value is a datetime.datetime, it is converted to a GPSTime
         before adding.

    Returns
    -------
    Union[GPSTime, np.ndarray]
        The sum of the `GPSTime` and `other`. If other is an np.array,
        returns the sum for each element
    """

    """
    Raises
    ------
    TypeError
        If other is not a supported type

    Notes
    -----
    .. note::
        Apart from adding of `datetime.timedelta` objects, this
        functionality does not exist with datetimes.

    .. note::
        This function can be used to "add" a negative amount of time,
        which can yield different results than subtraction.

    """
    if isinstance(other, bool):
        raise TypeError(
            "unsupported operand type(s) for -: '{}' and '{}'".format(
                type(self), type(other)
            )
        )
    if isinstance(other, int) or isinstance(other, float):
        gps_time_to_add = GPSTime(0, float(other))
    elif isinstance(other, datetime.timedelta):
        gps_time_to_add = GPSTime(0, other.total_seconds())
    elif isinstance(other, datetime.datetime):
        gps_time_to_add = GPSTime.from_datetime(other)
    elif isinstance(other, GPSTime):
        gps_time_to_add = other
    elif isinstance(other, np.ndarray):
        input = np.array([self])
        return input + other
    else:
        raise TypeError(
            "unsupported operand type(s) for +: '{}' and '{}'".format(
                type(self), type(other)
            )
        )

    week_num = self.week_number + gps_time_to_add.week_number
    seconds = self.seconds + gps_time_to_add.seconds
    femtoseconds = self.femtoseconds + gps_time_to_add.femtoseconds
    return GPSTime(week_num, seconds, femtoseconds)

__eq__(other)

Comparison: Equality.

.. note:: In this context "equality" is equivalent to "coincident"

Parameters

other : Union[GPSTime, datetime.datetime] The object to compare. Datatimes will be converted to GPSTime

Returns

bool True if the current object is the same time as its comparison

Source code in gps_time/core.py
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
def __eq__(self, other: Union[GPSTime, datetime.datetime]) -> bool:
    """Comparison: Equality.

    .. note:: In this context "equality" is equivalent to "coincident"

    Parameters
    ----------
    other : Union[GPSTime, datetime.datetime]
        The object to compare. Datatimes will be converted to `GPSTime`

    Returns
    -------
    bool
        True if the current object is the same time as its comparison
    """

    """
    Raises
    ------
    TypeError
        If an invalid type

    """
    if isinstance(other, datetime.datetime):
        other_time = GPSTime.from_datetime(other)
    elif isinstance(other, GPSTime):
        other_time = other
    else:
        raise TypeError(
            "'>' not supported between instances of '{}' and '{}'".format(
                type(self), type(other)
            )
        )
    return (self - other_time) == 0

__ge__(other)

Comparison: Greater Than or Equals.

Calls the __gt__() and __eq__() methods

Parameters

other : Union[GPSTime, datetime.datetime] The object to compare. Datatimes will be converted to GPSTime

Returns

bool True if the current object is after or at the same time as its comparison object.

Source code in gps_time/core.py
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
def __ge__(self, other: Union[GPSTime, datetime.datetime]) -> bool:
    """Comparison: Greater Than or Equals.

    Calls the `__gt__()` and `__eq__()` methods

    Parameters
    ----------
    other : Union[GPSTime, datetime.datetime]
        The object to compare. Datatimes will be converted to `GPSTime`

    Returns
    -------
    bool
        True if the current object is after or at the same time as its
        comparison object.
    """

    """        
    Raises
    ------
    TypeError
        If an invalid type

    """
    return self.__gt__(other) or self.__eq__(other)

__gt__(other)

Comparison: Greater Than.

.. note:: In this context "greater than" is equivalent to "after"

Parameters

other : Union[GPSTime, datetime.datetime] The object to compare. Datatimes will be converted to GPSTime

Returns

bool True if the current object is after its comparison

Source code in gps_time/core.py
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
def __gt__(self, other: Union[GPSTime, datetime.datetime]) -> bool:
    """Comparison: Greater Than.

    .. note:: In this context "greater than" is equivalent to "after"

    Parameters
    ----------
    other : Union[GPSTime, datetime.datetime]
        The object to compare. Datatimes will be converted to `GPSTime`

    Returns
    -------
    bool
        True if the current object is after its comparison
    """

    """
    Raises
    ------
    TypeError
        If an invalid type

    """
    if isinstance(other, datetime.datetime):
        other_time = GPSTime.from_datetime(other)
    elif isinstance(other, GPSTime):
        other_time = other
    else:
        raise TypeError(
            "'>' not supported between instances of '{}' and '{}'".format(
                type(self), type(other)
            )
        )
    return (self - other_time) > 0

__hash__()

Make GPSTime hashable.

Source code in gps_time/core.py
748
749
750
def __hash__(self):
    """Make GPSTime hashable."""
    return hash(str(self.week_number) + str(self.seconds) + str(self.femtoseconds))

__init__(week_number, *args, **kwargs)

Object constructor.

This sets the week number and the time of week and ensures that the time of week is a float. It also calls correct_time(), which checks to see if the time of week is negative or past the end of the week and adjust the values accordingly.

This constructor supports many different input arguments. However some sets of input arguments may result in truncation and errors if a float is provided when an int is expected.

Parameters

week_number : int The number of week args, *kwargs The time of week in various representations. If positional arguments are used, a single positional argument is interpreted as a time of week (i.e. a float), while two arguments are interpreted as seconds and femtoseconds. In the latter case, the values will be cast as integers, which may result in truncation. Keyword arguments function in much the same way, with "time_of_week", "seconds", and "femtoseconds" being the valid keyword arguments. If only "seconds" is given, it will be treated like "time_of_week". If no additional arguments are given, the time is assumed to be the start of the week.

Source code in gps_time/core.py
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
def __init__(self, week_number: int, *args, **kwargs) -> None:
    """Object constructor.

    This sets the week number and the time of week and ensures that the
    time of week is a float. It also calls `correct_time()`, which checks
    to see if the time of week is negative or past the end of the week
    and adjust the values accordingly.

    This constructor supports many different input arguments. However some
    sets of input arguments may result in truncation and errors if a
    `float` is provided when an `int` is expected.

    Parameters
    ----------
    week_number : int
        The number of week
    *args, **kwargs
        The time of week in various representations. If positional arguments
        are used, a single positional argument is interpreted as a time of
        week (i.e. a float), while two arguments are interpreted as seconds
        and femtoseconds. In the latter case, the values will be cast as
        integers, which may result in truncation. Keyword arguments function
        in much the same way, with "time_of_week", "seconds", and
        "femtoseconds" being the valid keyword arguments. If only "seconds"
        is given, it will be treated like "time_of_week". If no additional
        arguments are given, the time is assumed to be the start of the week.
    """

    """
    Raises
    ------
    ValueError
        If invalid arguments are given. Examples include:
        - Mixed positional and keyword arguments are not supported
        - More than two arguments are not supported
        - Keyword arguments "time_of_week" and "femtoseconds" cannot be
          used together.

    """
    self.yaml_tag: str = u"!GPSTime"
    if len(args) > 0 and len(kwargs) > 0:
        raise ValueError(
            "GPSTime does not support both positional and keyword arguments."
        )

    self.week_number = int(week_number)
    if len(args) > 2:  # If more than 3 args (week + 2 times)
        raise ValueError(
            "Only up to three arguments allowed (Week number, seconds, "
            "and femtoseconds)"
        )
    elif len(args) == 2:
        if isinstance(args[0], float) or isinstance(args[1], float):
            logger.warning(
                "Two times given, but at least one is a float. Decimal "
                "values will be truncated"
            )
        self.seconds = int(args[0])
        self.femtoseconds = int(args[1])
    elif len(args) == 1:
        self.time_of_week = args[0]
    else:
        if len(kwargs) > 2:
            raise ValueError("Too many arguments")
        elif len(kwargs) == 0:
            logger.warning(
                "No time of week information. Defaulting to start of week"
            )
            self.seconds = 0
            self.femtoseconds = 0

        elif "femtoseconds" in kwargs:
            if "time_of_week" in kwargs:
                raise ValueError(
                    """Keyword arguments "time_of_week" and "femtoseconds"
                    are incompatible."""
                )
            elif "seconds" in kwargs:
                if isinstance(kwargs["seconds"], float) or isinstance(
                    kwargs["femtoseconds"], float
                ):
                    logger.warning(
                        "Two times given, but at least one is a float. "
                        "Decimal values will be truncated"
                    )
                self.seconds = int(kwargs["seconds"])
                self.femtoseconds = int(kwargs["femtoseconds"])
            else:
                raise ValueError(
                    """Keyword argument "femtoseconds" must be
                    accompanied by "seconds"."""
                )
        elif "seconds" in kwargs:
            logger.warning(
                "seconds given with no femtoseconds. Will be handled "
                "as time of week"
            )
            self.time_of_week = float(kwargs["seconds"])
        elif "time_of_week" in kwargs:
            self.time_of_week = float(kwargs["time_of_week"])
        else:
            raise ValueError("Invalid Keyword arguments")

    self.correct_time()
    if self.week_number < 0:
        logger.warning("Week number is less than 0")

__le__(other)

Comparison: Less Than or Equals.

Calls the __lt__() and __eq__() methods

Parameters

other : Union[GPSTime, datetime.datetime] The object to compare. Datatimes will be converted to GPSTime

Returns

bool True if the current object is before or at the same time as its comparison object.

Source code in gps_time/core.py
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
def __le__(self, other: Union[GPSTime, datetime.datetime]) -> bool:
    """Comparison: Less Than or Equals.

    Calls the `__lt__()` and `__eq__()` methods

    Parameters
    ----------
    other : Union[GPSTime, datetime.datetime]
        The object to compare. Datatimes will be converted to `GPSTime`

    Returns
    -------
    bool
        True if the current object is before or at the same time as its
        comparison object.
    """

    """
    Raises
    ------
    TypeError
        If an invalid type

    """
    return self.__lt__(other) or self.__eq__(other)

__lt__(other)

Comparison: Less Than.

.. note:: In this context "less than" is equivalent to "before"

Parameters

other : Union[GPSTime, datetime.datetime] The object to compare. Datatimes will be converted to GPSTime

Returns

bool True if the current object is before its comparison

Source code in gps_time/core.py
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
def __lt__(self, other: Union[GPSTime, datetime.datetime]) -> bool:
    """Comparison: Less Than.

    .. note:: In this context "less than" is equivalent to "before"

    Parameters
    ----------
    other : Union[GPSTime, datetime.datetime]
        The object to compare. Datatimes will be converted to `GPSTime`

    Returns
    -------
    bool
        True if the current object is before its comparison
    """

    """
    Raises
    ------
    TypeError
        If an invalid type

    """
    if isinstance(other, datetime.datetime):
        other_time = GPSTime.from_datetime(other)
    elif isinstance(other, GPSTime):
        other_time = other
    else:
        raise TypeError(
            "'<' not supported between instances of '{}' and '{}'".format(
                type(self), type(other)
            )
        )
    return (self - other_time) < 0

__ne__(other)

Comparison: Not Equals.

Inverts the result of the __eq__() method

Parameters

other : Union[GPSTime, datetime.datetime] The object to compare. Datatimes will be converted to GPSTime

Returns

bool True if the current object is not the same time as its comparison

Source code in gps_time/core.py
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
def __ne__(self, other: Union[GPSTime, datetime.datetime]) -> bool:
    """Comparison: Not Equals.

    Inverts the result of the `__eq__()` method

    Parameters
    ----------
    other : Union[GPSTime, datetime.datetime]
        The object to compare. Datatimes will be converted to `GPSTime`

    Returns
    -------
    bool
        True if the current object is not the same time as its comparison
    """

    """
    Raises
    ------
    TypeError
        If an invalid type

    """
    return not (self.__eq__(other))

__repr__()

Representation of the object.

Returns

str The representation of the object

Source code in gps_time/core.py
752
753
754
755
756
757
758
759
760
761
762
763
def __repr__(self) -> str:
    """Representation of the object.

    Returns
    -------
    str
        The representation of the object

    """
    return "GPSTime(week_number={}, time_of_week={})".format(
        self.week_number, self.time_of_week
    )

__sub__(other)

Subtraction.

This method is used to represent subtraction. Depending on the type of the arguments, it can be used to find the time offset by an amount or the number of seconds between two times.

Parameters

other : Union[int, float, GPSTime, datetime.datetime, datetime.timedelta, np.ndarray] The other value to subtract from the GPSTime. int and float values are the number of seconds to subtract from the GPSTime. GPSTime and datetime.timedelta have explicit unit definitions that are used. If the value is a datetime.datetime, it is converted to a GPSTime before subtracting.

Returns

Union[GPSTime, float, np.ndarray] A float will be return if both values are GPSTime objects that represents the number of seconds between the objects. A GPSTime will be returned otherwise and it represents offsetting the time backward by the amount given. If the input is an np.ndarray, then returns the operation for each element

Notes
-----
Subtracting a non-`GPSTime` object is equivalent to adding the opposite
of its value
Source code in gps_time/core.py
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
def __sub__(
    self,
    other: Union[
        int, float, GPSTime, datetime.datetime, datetime.timedelta, np.ndarray
    ],
) -> Union[GPSTime, float, np.ndarray]:
    """Subtraction.

    This method is used to represent subtraction. Depending on the type of
    the arguments, it can be used to find the time offset by an amount or
    the number of seconds between two times.

    Parameters
    ----------
    other : Union[int, float, GPSTime, datetime.datetime,
                  datetime.timedelta, np.ndarray]
        The other value to subtract from the `GPSTime`. `int` and `float`
        values are the number of seconds to subtract from the `GPSTime`.
        `GPSTime` and `datetime.timedelta` have explicit unit definitions
        that are used. If the value is a datetime.datetime, it is
        converted to a GPSTime before subtracting.

    Returns
    -------
    Union[GPSTime, float, np.ndarray]
        A float will be return if both values are `GPSTime` objects that
        represents the number of seconds between the objects. A GPSTime
        will be returned otherwise and it represents offsetting the time
        backward by the amount given. If the input is an np.ndarray, then
        returns the operation for each element

        Notes
        -----
        Subtracting a non-`GPSTime` object is equivalent to adding the opposite
        of its value
    """

    """
    Raises
    ------
    TypeError
        If other is not a supported type


    """
    if isinstance(other, bool):
        raise TypeError(
            "unsupported operand type(s) for -: '{}' and '{}'".format(
                type(self), type(other)
            )
        )
    if isinstance(other, int) or isinstance(other, float):
        sec_to_sub, femto_to_sub = _tow2sec(float(other))

        return GPSTime(
            self.week_number,
            self.seconds - sec_to_sub,
            self.femtoseconds - femto_to_sub,
        )

    elif isinstance(other, datetime.timedelta):
        sec_to_sub, femto_to_sub = _tow2sec(float(other.total_seconds()))

        return GPSTime(
            self.week_number,
            self.seconds - sec_to_sub,
            self.femtoseconds - femto_to_sub,
        )

    elif isinstance(other, datetime.datetime):
        other_gpstime = GPSTime.from_datetime(other)

        weeks_diff = self.week_number - other_gpstime.week_number
        sec_diff = self.seconds - other_gpstime.seconds
        femto_diff = self.femtoseconds - other_gpstime.femtoseconds

        return float(
            weeks_diff * _SEC_IN_WEEK + sec_diff + femto_diff * _FEMTO_SEC_TO_SEC
        )

    elif isinstance(other, GPSTime):
        weeks_diff = self.week_number - other.week_number
        sec_diff = self.seconds - other.seconds
        femto_diff = self.femtoseconds - other.femtoseconds

        return float(
            weeks_diff * _SEC_IN_WEEK + sec_diff + femto_diff * _FEMTO_SEC_TO_SEC
        )

    elif isinstance(other, np.ndarray):
        if other.dtype == object:
            _type = np.reshape(other, sum([i for i in other.shape]))[0].__class__

            if _type in (self.__class__, datetime.datetime):
                input = np.array([self])
                return np.array(input - other, dtype=float)
            elif _type is datetime.timedelta:
                input = np.array([self])
                return np.array(input - other, dtype=object)
        elif other.dtype in (
            int,
            float,
        ):
            input = np.array([self])
            return np.array(input - other, dtype=object)

    else:
        raise TypeError(
            "unsupported operand type(s) for -: '{}' and '{}'".format(
                type(self), type(other)
            )
        )

correct_weeks()

Correct the week number based on the time of week.

If the time of week is less than 0 or greater than 604800 seconds, then the week number and time of week will be corrected to ensure that the time of week is within the week indicated by the week number.

Returns

None

Source code in gps_time/core.py
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
def correct_weeks(self) -> None:
    """Correct the week number based on the time of week.

    If the time of week is less than 0 or greater than 604800 seconds,
    then the week number and time of week will be corrected to ensure that
    the time of week is within the week indicated by the week number.

    Returns
    -------
    None

    """
    logger.warning(
        "The correct_weeks() method will be deprecated in a future version. Use the correct_time() method instead."
    )
    if (self.time_of_week >= _SEC_IN_WEEK) or (self.time_of_week < 0):
        weeks_to_add = int(self.time_of_week // _SEC_IN_WEEK)
        new_time_of_week = float(self.time_of_week % _SEC_IN_WEEK)

        self.week_number += weeks_to_add
        self.time_of_week = new_time_of_week
    else:
        pass

from_datetime(time) classmethod

Create a GPSTime for a datetime.

Parameters

time : datetime.datetime The datetime that will be converted to a GPSTime

Returns

GPSTime The GPSTime corresponding to the datetime. This is a lossless conversion.

Source code in gps_time/core.py
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
@classmethod
def from_datetime(cls, time: datetime.datetime) -> GPSTime:
    """Create a `GPSTime` for a datetime.

    Parameters
    ----------
    time : datetime.datetime
        The datetime that will be converted to a `GPSTime`

    Returns
    -------
    GPSTime
        The `GPSTime` corresponding to the datetime. This is a lossless
        conversion.
    """ 

    """
    Raises
    ------
    TypeError
        If the input value is not a datetime

    Notes
    -----
    This is a classmethod and thus can be called without instantiating the
    object first.

    """
    if not isinstance(time, datetime.datetime):
        raise TypeError("time must be a datetime")

    week_num, tow = datetime2tow(time)

    return cls(week_num, tow)

from_yaml(constructor, node) classmethod

YAML Constructor.

This YAML constructor is used to load a GPSTime from a YAML file. It must be registered with the YAML loader. This is accomplished using

import ruamel.yaml
yaml = ruamel.yaml.YAML()
yaml.register_class(GPSTime)

This class method is primarily used to add a constructor to an instance of ruamel.yaml. Its functionality as a traditional classmethod is limited.

.. note:: YAML Module This constructor is meant to be used with ruamel.yaml. It has not been tested with pyyaml (the more common YAML library.)

Source code in gps_time/core.py
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
@classmethod
def from_yaml(
    cls: type, constructor: ruamel.yaml.Constructor, node: ruamel.yaml.MappingNode
) -> GPSTime:
    """YAML Constructor.

    This YAML constructor is used to load a GPSTime from a YAML file. It must be
    registered with the YAML loader. This is accomplished using
    ```python3
    import ruamel.yaml
    yaml = ruamel.yaml.YAML()
    yaml.register_class(GPSTime)
    ```

    This class method is primarily used to add a constructor to an instance of
    ruamel.yaml. Its functionality as a traditional classmethod is limited.

    .. note:: YAML Module
        This constructor is meant to be used with ruamel.yaml. It has not been tested
        with pyyaml (the more common YAML library.)

    """
    nodes = node.value
    week_number = None
    seconds = None
    femtoseconds = None
    time_of_week = None
    for i in range(0, len(nodes)):
        node_name = nodes[i][0].value
        if node_name == "week_number":
            week_number = constructor.construct_scalar(nodes[i][1])
        elif node_name == "seconds":
            seconds = constructor.construct_scalar(nodes[i][1])
        elif node_name == "femtoseconds":
            femtoseconds = constructor.construct_scalar(nodes[i][1])
        elif node_name == "time_of_week":
            time_of_week = constructor.construct_scalar(nodes[i][1])

    if seconds is None and time_of_week is None:
        raise ValueError("The YAML file lacked both a time_of_week and a seconds")
    if seconds is not None and time_of_week is not None:
        raise ValueError(
            "YAML file defines both time_of_week and seconds (incompatible)"
        )
    elif time_of_week is not None and femtoseconds is not None:
        raise ValueError(
            "YAML file defines both time_of_week and femtoseconds (incompatible)"
        )
    elif seconds is not None and femtoseconds is None:
        seconds, femtoseconds = _tow2sec(float(seconds))
    elif time_of_week is not None:
        seconds, femtoseconds = _tow2sec(float(time_of_week))

    return cls(int(week_number), int(seconds), int(femtoseconds))

to_datetime()

Convert the GPSTime to a datetime.

This method calls tow2datetime() to convert the GPSTime to a datetime object.

Returns

datetime.datetime The equivalent datetime representation of the GPSTime

Notes

.. note:: Datetimes are limited to microsecond resolution, so this conversion may lose some fidelity.

Source code in gps_time/core.py
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
def to_datetime(self) -> datetime.datetime:
    """Convert the `GPSTime` to a datetime.

    This method calls `tow2datetime()` to convert the `GPSTime` to a
    datetime object.

    Returns
    -------
    datetime.datetime
        The equivalent datetime representation of the `GPSTime`

    Notes
    -----
    .. note::
        Datetimes are limited to microsecond resolution, so this
        conversion may lose some fidelity.

    """
    return tow2datetime(self.week_number, self.time_of_week)

to_zcount()

Get the current Z-Count.

Returns

float The time of week divided by 1.5

Source code in gps_time/core.py
324
325
326
327
328
329
330
331
332
333
def to_zcount(self) -> float:
    """Get the current Z-Count.

    Returns
    -------
    float
        The time of week divided by 1.5

    """
    return self.time_of_week / 1.5