18
18
utc ,
19
19
)
20
20
21
- from pandas ._libs .tslibs .dtypes import NpyDatetimeUnit
21
+ from pandas ._libs .tslibs .dtypes import (
22
+ NpyDatetimeUnit ,
23
+ npy_unit_to_abbrev ,
24
+ )
22
25
from pandas ._libs .tslibs .timezones import (
23
26
dateutil_gettz as gettz ,
24
27
get_timezone ,
@@ -884,22 +887,29 @@ def test_to_period(self, dt64, ts):
884
887
)
885
888
def test_addsub_timedeltalike_non_nano (self , dt64 , ts , td ):
886
889
890
+ if isinstance (td , Timedelta ):
891
+ # td._reso is ns
892
+ exp_reso = td ._reso
893
+ else :
894
+ # effective td._reso is s
895
+ exp_reso = ts ._reso
896
+
887
897
result = ts - td
888
898
expected = Timestamp (dt64 ) - td
889
899
assert isinstance (result , Timestamp )
890
- assert result ._reso == ts . _reso
900
+ assert result ._reso == exp_reso
891
901
assert result == expected
892
902
893
903
result = ts + td
894
904
expected = Timestamp (dt64 ) + td
895
905
assert isinstance (result , Timestamp )
896
- assert result ._reso == ts . _reso
906
+ assert result ._reso == exp_reso
897
907
assert result == expected
898
908
899
909
result = td + ts
900
910
expected = td + Timestamp (dt64 )
901
911
assert isinstance (result , Timestamp )
902
- assert result ._reso == ts . _reso
912
+ assert result ._reso == exp_reso
903
913
assert result == expected
904
914
905
915
def test_addsub_offset (self , ts_tz ):
@@ -944,27 +954,35 @@ def test_sub_datetimelike_mismatched_reso(self, ts_tz):
944
954
result = ts - other
945
955
assert isinstance (result , Timedelta )
946
956
assert result .value == 0
947
- assert result ._reso == min (ts ._reso , other ._reso )
957
+ assert result ._reso == max (ts ._reso , other ._reso )
948
958
949
959
result = other - ts
950
960
assert isinstance (result , Timedelta )
951
961
assert result .value == 0
952
- assert result ._reso == min (ts ._reso , other ._reso )
962
+ assert result ._reso == max (ts ._reso , other ._reso )
953
963
954
- msg = "Timestamp subtraction with mismatched resolutions"
955
964
if ts ._reso < other ._reso :
956
965
# Case where rounding is lossy
957
966
other2 = other + Timedelta ._from_value_and_reso (1 , other ._reso )
958
- with pytest .raises (ValueError , match = msg ):
959
- ts - other2
960
- with pytest .raises (ValueError , match = msg ):
961
- other2 - ts
967
+ exp = ts ._as_unit (npy_unit_to_abbrev (other ._reso )) - other2
968
+
969
+ res = ts - other2
970
+ assert res == exp
971
+ assert res ._reso == max (ts ._reso , other ._reso )
972
+
973
+ res = other2 - ts
974
+ assert res == - exp
975
+ assert res ._reso == max (ts ._reso , other ._reso )
962
976
else :
963
977
ts2 = ts + Timedelta ._from_value_and_reso (1 , ts ._reso )
964
- with pytest .raises (ValueError , match = msg ):
965
- ts2 - other
966
- with pytest .raises (ValueError , match = msg ):
967
- other - ts2
978
+ exp = ts2 - other ._as_unit (npy_unit_to_abbrev (ts2 ._reso ))
979
+
980
+ res = ts2 - other
981
+ assert res == exp
982
+ assert res ._reso == max (ts ._reso , other ._reso )
983
+ res = other - ts2
984
+ assert res == - exp
985
+ assert res ._reso == max (ts ._reso , other ._reso )
968
986
969
987
def test_sub_timedeltalike_mismatched_reso (self , ts_tz ):
970
988
# case with non-lossy rounding
@@ -984,32 +1002,41 @@ def test_sub_timedeltalike_mismatched_reso(self, ts_tz):
984
1002
result = ts + other
985
1003
assert isinstance (result , Timestamp )
986
1004
assert result == ts
987
- assert result ._reso == min (ts ._reso , other ._reso )
1005
+ assert result ._reso == max (ts ._reso , other ._reso )
988
1006
989
1007
result = other + ts
990
1008
assert isinstance (result , Timestamp )
991
1009
assert result == ts
992
- assert result ._reso == min (ts ._reso , other ._reso )
1010
+ assert result ._reso == max (ts ._reso , other ._reso )
993
1011
994
- msg = "Timestamp addition with mismatched resolutions"
995
1012
if ts ._reso < other ._reso :
996
1013
# Case where rounding is lossy
997
1014
other2 = other + Timedelta ._from_value_and_reso (1 , other ._reso )
998
- with pytest .raises (ValueError , match = msg ):
999
- ts + other2
1000
- with pytest .raises (ValueError , match = msg ):
1001
- other2 + ts
1015
+ exp = ts ._as_unit (npy_unit_to_abbrev (other ._reso )) + other2
1016
+ res = ts + other2
1017
+ assert res == exp
1018
+ assert res ._reso == max (ts ._reso , other ._reso )
1019
+ res = other2 + ts
1020
+ assert res == exp
1021
+ assert res ._reso == max (ts ._reso , other ._reso )
1002
1022
else :
1003
1023
ts2 = ts + Timedelta ._from_value_and_reso (1 , ts ._reso )
1004
- with pytest .raises (ValueError , match = msg ):
1005
- ts2 + other
1006
- with pytest .raises (ValueError , match = msg ):
1007
- other + ts2
1024
+ exp = ts2 + other ._as_unit (npy_unit_to_abbrev (ts2 ._reso ))
1008
1025
1009
- msg = "Addition between Timestamp and Timedelta with mismatched resolutions"
1010
- with pytest .raises (ValueError , match = msg ):
1011
- # With a mismatched td64 as opposed to Timedelta
1012
- ts + np .timedelta64 (1 , "ns" )
1026
+ res = ts2 + other
1027
+ assert res == exp
1028
+ assert res ._reso == max (ts ._reso , other ._reso )
1029
+ res = other + ts2
1030
+ assert res == exp
1031
+ assert res ._reso == max (ts ._reso , other ._reso )
1032
+
1033
+ def test_sub_timedelta64_mismatched_reso (self , ts_tz ):
1034
+ ts = ts_tz
1035
+
1036
+ res = ts + np .timedelta64 (1 , "ns" )
1037
+ exp = ts ._as_unit ("ns" ) + np .timedelta64 (1 , "ns" )
1038
+ assert exp == res
1039
+ assert exp ._reso == NpyDatetimeUnit .NPY_FR_ns .value
1013
1040
1014
1041
def test_min (self , ts ):
1015
1042
assert ts .min <= ts
0 commit comments