@@ -88,6 +88,13 @@ def test_td_add_datetimelike_scalar(self, op):
88
88
result = op (td , NaT )
89
89
assert result is NaT
90
90
91
+ def test_td_add_timestamp_overflow (self ):
92
+ with pytest .raises (OverflowError ):
93
+ Timestamp ("1700-01-01" ) + Timedelta (13 * 19999 , unit = "D" )
94
+
95
+ with pytest .raises (OverflowError ):
96
+ Timestamp ("1700-01-01" ) + timedelta (days = 13 * 19999 )
97
+
91
98
@pytest .mark .parametrize ("op" , [operator .add , ops .radd ])
92
99
def test_td_add_td (self , op ):
93
100
td = Timedelta (10 , unit = "d" )
@@ -365,6 +372,26 @@ def test_td_div_timedeltalike_scalar(self):
365
372
366
373
assert np .isnan (td / NaT )
367
374
375
+ def test_td_div_td64_non_nano (self ):
376
+
377
+ # truediv
378
+ td = Timedelta ("1 days 2 hours 3 ns" )
379
+ result = td / np .timedelta64 (1 , "D" )
380
+ assert result == td .value / float (86400 * 1e9 )
381
+ result = td / np .timedelta64 (1 , "s" )
382
+ assert result == td .value / float (1e9 )
383
+ result = td / np .timedelta64 (1 , "ns" )
384
+ assert result == td .value
385
+
386
+ # floordiv
387
+ td = Timedelta ("1 days 2 hours 3 ns" )
388
+ result = td // np .timedelta64 (1 , "D" )
389
+ assert result == 1
390
+ result = td // np .timedelta64 (1 , "s" )
391
+ assert result == 93600
392
+ result = td // np .timedelta64 (1 , "ns" )
393
+ assert result == td .value
394
+
368
395
def test_td_div_numeric_scalar (self ):
369
396
# GH#19738
370
397
td = Timedelta (10 , unit = "d" )
@@ -589,6 +616,13 @@ def test_td_rfloordiv_timedeltalike_array(self):
589
616
expected = np .array ([10 , np .nan ])
590
617
tm .assert_numpy_array_equal (res , expected )
591
618
619
+ def test_td_rfloordiv_intarray (self ):
620
+ # deprecated GH#19761, enforced GH#29797
621
+ ints = np .array ([1349654400 , 1349740800 , 1349827200 , 1349913600 ]) * 10 ** 9
622
+
623
+ with pytest .raises (TypeError , match = "Invalid dtype" ):
624
+ ints // Timedelta (1 , unit = "s" )
625
+
592
626
def test_td_rfloordiv_numeric_series (self ):
593
627
# GH#18846
594
628
td = Timedelta (hours = 3 , minutes = 3 )
@@ -796,3 +830,129 @@ def test_rdivmod_invalid(self):
796
830
def test_td_op_timedelta_timedeltalike_array (self , op , arr ):
797
831
with pytest .raises (TypeError ):
798
832
op (arr , Timedelta ("1D" ))
833
+
834
+
835
+ class TestTimedeltaComparison :
836
+ def test_compare_tick (self , tick_classes ):
837
+ cls = tick_classes
838
+
839
+ off = cls (4 )
840
+ td = off .delta
841
+ assert isinstance (td , Timedelta )
842
+
843
+ assert td == off
844
+ assert not td != off
845
+ assert td <= off
846
+ assert td >= off
847
+ assert not td < off
848
+ assert not td > off
849
+
850
+ assert not td == 2 * off
851
+ assert td != 2 * off
852
+ assert td <= 2 * off
853
+ assert td < 2 * off
854
+ assert not td >= 2 * off
855
+ assert not td > 2 * off
856
+
857
+ def test_comparison_object_array (self ):
858
+ # analogous to GH#15183
859
+ td = Timedelta ("2 days" )
860
+ other = Timedelta ("3 hours" )
861
+
862
+ arr = np .array ([other , td ], dtype = object )
863
+ res = arr == td
864
+ expected = np .array ([False , True ], dtype = bool )
865
+ assert (res == expected ).all ()
866
+
867
+ # 2D case
868
+ arr = np .array ([[other , td ], [td , other ]], dtype = object )
869
+ res = arr != td
870
+ expected = np .array ([[True , False ], [False , True ]], dtype = bool )
871
+ assert res .shape == expected .shape
872
+ assert (res == expected ).all ()
873
+
874
+ def test_compare_timedelta_ndarray (self ):
875
+ # GH#11835
876
+ periods = [Timedelta ("0 days 01:00:00" ), Timedelta ("0 days 01:00:00" )]
877
+ arr = np .array (periods )
878
+ result = arr [0 ] > arr
879
+ expected = np .array ([False , False ])
880
+ tm .assert_numpy_array_equal (result , expected )
881
+
882
+ @pytest .mark .skip (reason = "GH#20829 is reverted until after 0.24.0" )
883
+ def test_compare_custom_object (self ):
884
+ """
885
+ Make sure non supported operations on Timedelta returns NonImplemented
886
+ and yields to other operand (GH#20829).
887
+ """
888
+
889
+ class CustomClass :
890
+ def __init__ (self , cmp_result = None ):
891
+ self .cmp_result = cmp_result
892
+
893
+ def generic_result (self ):
894
+ if self .cmp_result is None :
895
+ return NotImplemented
896
+ else :
897
+ return self .cmp_result
898
+
899
+ def __eq__ (self , other ):
900
+ return self .generic_result ()
901
+
902
+ def __gt__ (self , other ):
903
+ return self .generic_result ()
904
+
905
+ t = Timedelta ("1s" )
906
+
907
+ assert not (t == "string" )
908
+ assert not (t == 1 )
909
+ assert not (t == CustomClass ())
910
+ assert not (t == CustomClass (cmp_result = False ))
911
+
912
+ assert t < CustomClass (cmp_result = True )
913
+ assert not (t < CustomClass (cmp_result = False ))
914
+
915
+ assert t == CustomClass (cmp_result = True )
916
+
917
+ @pytest .mark .parametrize ("val" , ["string" , 1 ])
918
+ def test_compare_unknown_type (self , val ):
919
+ # GH#20829
920
+ t = Timedelta ("1s" )
921
+ with pytest .raises (TypeError ):
922
+ t >= val
923
+ with pytest .raises (TypeError ):
924
+ t > val
925
+ with pytest .raises (TypeError ):
926
+ t <= val
927
+ with pytest .raises (TypeError ):
928
+ t < val
929
+
930
+
931
+ def test_ops_notimplemented ():
932
+ class Other :
933
+ pass
934
+
935
+ other = Other ()
936
+
937
+ td = Timedelta ("1 day" )
938
+ assert td .__add__ (other ) is NotImplemented
939
+ assert td .__sub__ (other ) is NotImplemented
940
+ assert td .__truediv__ (other ) is NotImplemented
941
+ assert td .__mul__ (other ) is NotImplemented
942
+ assert td .__floordiv__ (other ) is NotImplemented
943
+
944
+
945
+ def test_ops_error_str ():
946
+ # GH#13624
947
+ td = Timedelta ("1 day" )
948
+
949
+ for left , right in [(td , "a" ), ("a" , td )]:
950
+
951
+ with pytest .raises (TypeError ):
952
+ left + right
953
+
954
+ with pytest .raises (TypeError ):
955
+ left > right
956
+
957
+ assert not left == right
958
+ assert left != right
0 commit comments