@@ -277,6 +277,22 @@ def test_from_float(self):
277277 self .assertEqual (r , case [1 ],
278278 msg = "Timestamp.from_float{!r} == {!r}, expected {!r}" .format (case [0 ], r , case [1 ]))
279279
280+ def test_to_float (self ):
281+ """This tests that timestamps can be created from a float."""
282+ cases = [
283+ ((float (1.0 )), Timestamp (1 , 0 )),
284+ ((float (1_000_000_000 )), Timestamp (1_000_000_000 , 0 )),
285+ ((float (2.76 )), Timestamp (2 , 760_000_000 )),
286+ ((float (- 3.14 )), Timestamp (3 , 140_000_000 , - 1 )),
287+ ((float (0.02 )), Timestamp (0 , 20_000_000 ))
288+ ]
289+
290+ for case in cases :
291+ with self .subTest (case = case ):
292+ r = case [1 ].to_float ()
293+ self .assertEqual (r , case [1 ],
294+ msg = "{!r},to_float() == {!r}, expected {!r}" .format (case [1 ], r , case [0 ]))
295+
280296 def test_set_value (self ):
281297 """This tests that timestamps cannot have their value set."""
282298 tests_ts = [
@@ -730,6 +746,12 @@ def test_convert_iso_utc(self):
730746 """This tests that conversion to and from ISO date format UTC time works as expected."""
731747
732748 tests = [
749+ (Timestamp (62135596800 , 0 , - 1 ), "0001-01-01T00:00:00.000000000Z" ),
750+ (Timestamp (1 , 0 , - 1 ), "1969-12-31T23:59:59.000000000Z" ),
751+ (Timestamp (0 , 999999999 , - 1 ), "1969-12-31T23:59:59.000000001Z" ),
752+ (Timestamp (0 , 1 , - 1 ), "1969-12-31T23:59:59.999999999Z" ),
753+ (Timestamp (0 , 0 , 1 ), "1970-01-01T00:00:00.000000000Z" ),
754+
733755 (Timestamp (1424177663 , 102003 ), "2015-02-17T12:53:48.000102003Z" ),
734756
735757 # the leap second is 23:59:60
@@ -751,7 +773,8 @@ def test_convert_iso_utc(self):
751773 (Timestamp (1341100835 , 100000000 ), "2012-07-01T00:00:00.100000000Z" ),
752774 (Timestamp (1341100835 , 999999999 ), "2012-07-01T00:00:00.999999999Z" ),
753775
754- (Timestamp (283996818 , 0 ), "1979-01-01T00:00:00.000000000Z" ) # 1979
776+ (Timestamp (283996818 , 0 ), "1979-01-01T00:00:00.000000000Z" ), # 1979
777+ (Timestamp (253402300836 , 999999999 ), "9999-12-31T23:59:59.999999999Z" )
755778 ]
756779
757780 for t in tests :
@@ -827,9 +850,16 @@ def test_from_datetime(self):
827850 """Conversion from python's datetime object."""
828851
829852 tests = [
853+ (datetime (1 , 1 , 1 , 0 , 0 , 0 , 0 , tz .gettz ('UTC' )), Timestamp (62135596800 , 0 , - 1 )),
854+ (datetime (1969 , 12 , 31 , 23 , 59 , 59 , 0 , tz .gettz ('UTC' )), Timestamp (1 , 0 , - 1 )),
855+ (datetime (1969 , 12 , 31 , 23 , 59 , 59 , 1 , tz .gettz ('UTC' )), Timestamp (0 , 999999000 , - 1 )),
856+ (datetime (1969 , 12 , 31 , 23 , 59 , 59 , 999999 , tz .gettz ('UTC' )), Timestamp (0 , 1000 , - 1 )),
830857 (datetime (1970 , 1 , 1 , 0 , 0 , 0 , 0 , tz .gettz ('UTC' )), Timestamp (0 , 0 )),
831858 (datetime (1983 , 3 , 29 , 15 , 45 , 0 , 0 , tz .gettz ('UTC' )), Timestamp (417800721 , 0 )),
832859 (datetime (2017 , 12 , 5 , 16 , 33 , 12 , 196 , tz .gettz ('UTC' )), Timestamp (1512491629 , 196000 )),
860+ (datetime (2514 , 1 , 1 , 0 , 0 , 0 , 0 , tz .gettz ('UTC' )), Timestamp (17166988837 , 0 , 1 )),
861+ # Stopping around here because high datetime values have a floating point error.
862+ # See https://stackoverflow.com/a/75582241.
833863 ]
834864
835865 for t in tests :
@@ -839,10 +869,18 @@ def test_to_datetime(self):
839869 """Conversion to python's datetime object."""
840870
841871 tests = [
872+ (datetime (1 , 1 , 1 , 0 , 0 , 0 , 0 , tz .gettz ('UTC' )), Timestamp (62135596800 , 0 , - 1 )),
873+ (datetime (1969 , 12 , 31 , 23 , 59 , 59 , 0 , tz .gettz ('UTC' )), Timestamp (1 , 0 , - 1 )),
874+ (datetime (1969 , 12 , 31 , 23 , 59 , 59 , 1 , tz .gettz ('UTC' )), Timestamp (0 , 999999000 , - 1 )),
875+ (datetime (1969 , 12 , 31 , 23 , 59 , 59 , 999999 , tz .gettz ('UTC' )), Timestamp (0 , 1000 , - 1 )),
842876 (datetime (1970 , 1 , 1 , 0 , 0 , 0 , 0 , tz .gettz ('UTC' )), Timestamp (0 , 0 )),
877+ (datetime (1970 , 1 , 1 , 0 , 0 , 0 , 1 , tz .gettz ('UTC' )), Timestamp (0 , 1000 )),
843878 (datetime (1983 , 3 , 29 , 15 , 45 , 0 , 0 , tz .gettz ('UTC' )), Timestamp (417800721 , 0 )),
844879 (datetime (2017 , 12 , 5 , 16 , 33 , 12 , 196 , tz .gettz ('UTC' )), Timestamp (1512491629 , 196000 )),
845880 (datetime (2017 , 12 , 5 , 16 , 33 , 13 , 0 , tz .gettz ('UTC' )), Timestamp (1512491629 , 999999999 )),
881+ (datetime (2514 , 1 , 1 , 0 , 0 , 0 , 0 , tz .gettz ('UTC' )), Timestamp (17166988837 , 0 , 1 )),
882+ # Stopping around here because high datetime values have a floating point error.
883+ # See https://stackoverflow.com/a/75582241
846884 ]
847885
848886 for t in tests :
@@ -879,3 +917,46 @@ def test_get_leap_seconds(self):
879917
880918 for t in tests :
881919 self .assertEqual (t [0 ].get_leap_seconds (), t [1 ])
920+
921+ def test_from_unix (self ):
922+ tests = [
923+ ((Timestamp .MAX_SECONDS - 1 , Timestamp .MAX_NANOSEC - 1 , - 1 , False ), # 0 leap seconds
924+ Timestamp (Timestamp .MAX_SECONDS - 1 , Timestamp .MAX_NANOSEC - 1 , - 1 )), # 0 leap seconds
925+ ((1000 , 0 , - 1 , False ), Timestamp (1000 , 0 , - 1 )), # 0 leap seconds
926+ ((63071999 , 999999999 , 1 , False ), Timestamp (63071999 , 999999999 )), # 0 leap seconds
927+ ((63071999 , 0 , 1 , True ), Timestamp (63072009 , 0 )), # 10 leap seconds at leap
928+ ((63072000 , 0 , 1 , False ), Timestamp (63072010 , 0 )), # 10 leap seconds
929+ ((63072008 , 999999999 , 1 , False ), Timestamp (63072018 , 999999999 )), # 10 leap seconds
930+ ((1512491592 , 0 , 1 , False ), Timestamp (1512491629 , 0 )), # 37 leap seconds
931+ ((Timestamp .MAX_SECONDS - 1 - 37 , Timestamp .MAX_NANOSEC - 1 , 1 , False ),
932+ Timestamp (Timestamp .MAX_SECONDS - 1 , Timestamp .MAX_NANOSEC - 1 )), # 37 leap seconds
933+ ]
934+
935+ for t in tests :
936+ self .assertEqual (Timestamp .from_unix (* t [0 ]), t [1 ])
937+
938+ def test_to_unix (self ):
939+ tests = [
940+ (Timestamp (Timestamp .MAX_SECONDS - 1 , Timestamp .MAX_NANOSEC - 1 , - 1 ), # 0 leap seconds
941+ (Timestamp .MAX_SECONDS - 1 , Timestamp .MAX_NANOSEC - 1 , - 1 , False )), # 0 leap seconds
942+ (Timestamp (1000 , 0 , - 1 ), (1000 , 0 , - 1 , False )), # 0 leap seconds
943+ (Timestamp (63072008 , 999999999 ), (63072008 , 999999999 , 1 , False )), # 0 leap seconds
944+ (Timestamp (63072009 , 0 ), (63071999 , 0 , 1 , True )), # 10 leap seconds at leap
945+ (Timestamp (63072010 , 0 ), (63072000 , 0 , 1 , False )), # 10 leap seconds
946+ (Timestamp (1512491629 , 0 ), (1512491592 , 0 , 1 , False )), # 37 leap seconds
947+ (Timestamp (Timestamp .MAX_SECONDS - 1 , Timestamp .MAX_NANOSEC - 1 ),
948+ (Timestamp .MAX_SECONDS - 1 - 37 , Timestamp .MAX_NANOSEC - 1 , 1 , False )), # 37 leap seconds
949+ ]
950+
951+ for t in tests :
952+ self .assertEqual (t [0 ].to_unix (), t [1 ])
953+
954+ def test_to_unix_float (self ):
955+ tests = [
956+ (Timestamp (63072008 , 999999999 ), 63072008 + 999999999 / 1000000000 ),
957+ (Timestamp (63072009 , 0 ), 63071999 ),
958+ (Timestamp (1000 , 0 , - 1 ), - 1000 )
959+ ]
960+
961+ for t in tests :
962+ self .assertEqual (t [0 ].to_unix_float (), t [1 ])
0 commit comments