44
44
iNaT ,
45
45
ints_to_pydatetime ,
46
46
ints_to_pytimedelta ,
47
- npy_unit_to_abbrev ,
48
47
to_offset ,
49
48
)
50
49
from pandas ._libs .tslibs .fields import (
@@ -1169,13 +1168,8 @@ def _add_datetimelike_scalar(self, other) -> DatetimeArray:
1169
1168
# Preserve our resolution
1170
1169
return DatetimeArray ._simple_new (result , dtype = result .dtype )
1171
1170
1172
- if self ._reso != other ._reso :
1173
- # Just as with Timestamp/Timedelta, we cast to the higher resolution
1174
- if self ._reso < other ._reso :
1175
- unit = npy_unit_to_abbrev (other ._reso )
1176
- self = self ._as_unit (unit )
1177
- else :
1178
- other = other ._as_unit (self ._unit )
1171
+ self , other = self ._ensure_matching_resos (other )
1172
+ self = cast ("TimedeltaArray" , self )
1179
1173
1180
1174
i8 = self .asi8
1181
1175
result = checked_add_with_arr (i8 , other .value , arr_mask = self ._isnan )
@@ -1208,16 +1202,10 @@ def _sub_datetimelike_scalar(self, other: datetime | np.datetime64):
1208
1202
# i.e. np.datetime64("NaT")
1209
1203
return self - NaT
1210
1204
1211
- other = Timestamp (other )
1205
+ ts = Timestamp (other )
1212
1206
1213
- if other ._reso != self ._reso :
1214
- if other ._reso < self ._reso :
1215
- other = other ._as_unit (self ._unit )
1216
- else :
1217
- unit = npy_unit_to_abbrev (other ._reso )
1218
- self = self ._as_unit (unit )
1219
-
1220
- return self ._sub_datetimelike (other )
1207
+ self , ts = self ._ensure_matching_resos (ts )
1208
+ return self ._sub_datetimelike (ts )
1221
1209
1222
1210
@final
1223
1211
def _sub_datetime_arraylike (self , other ):
@@ -1230,12 +1218,7 @@ def _sub_datetime_arraylike(self, other):
1230
1218
self = cast ("DatetimeArray" , self )
1231
1219
other = ensure_wrapped_if_datetimelike (other )
1232
1220
1233
- if other ._reso != self ._reso :
1234
- if other ._reso < self ._reso :
1235
- other = other ._as_unit (self ._unit )
1236
- else :
1237
- self = self ._as_unit (other ._unit )
1238
-
1221
+ self , other = self ._ensure_matching_resos (other )
1239
1222
return self ._sub_datetimelike (other )
1240
1223
1241
1224
@final
@@ -1319,17 +1302,11 @@ def _add_timedelta_arraylike(
1319
1302
raise ValueError ("cannot add indices of unequal length" )
1320
1303
1321
1304
other = ensure_wrapped_if_datetimelike (other )
1322
- other = cast ("TimedeltaArray" , other )
1305
+ tda = cast ("TimedeltaArray" , other )
1323
1306
self = cast ("DatetimeArray | TimedeltaArray" , self )
1324
1307
1325
- if self ._reso != other ._reso :
1326
- # Just as with Timestamp/Timedelta, we cast to the higher resolution
1327
- if self ._reso < other ._reso :
1328
- self = self ._as_unit (other ._unit )
1329
- else :
1330
- other = other ._as_unit (self ._unit )
1331
-
1332
- return self ._add_timedeltalike (other )
1308
+ self , tda = self ._ensure_matching_resos (tda )
1309
+ return self ._add_timedeltalike (tda )
1333
1310
1334
1311
@final
1335
1312
def _add_timedeltalike (self , other : Timedelta | TimedeltaArray ):
@@ -2098,6 +2075,17 @@ def _as_unit(self: TimelikeOpsT, unit: str) -> TimelikeOpsT:
2098
2075
new_values , dtype = new_dtype , freq = self .freq # type: ignore[call-arg]
2099
2076
)
2100
2077
2078
+ # TODO: annotate other as DatetimeArray | TimedeltaArray | Timestamp | Timedelta
2079
+ # with the return type matching input type. TypeVar?
2080
+ def _ensure_matching_resos (self , other ):
2081
+ if self ._reso != other ._reso :
2082
+ # Just as with Timestamp/Timedelta, we cast to the higher resolution
2083
+ if self ._reso < other ._reso :
2084
+ self = self ._as_unit (other ._unit )
2085
+ else :
2086
+ other = other ._as_unit (self ._unit )
2087
+ return self , other
2088
+
2101
2089
# --------------------------------------------------------------
2102
2090
2103
2091
def __array_ufunc__ (self , ufunc : np .ufunc , method : str , * inputs , ** kwargs ):
0 commit comments