@@ -206,44 +206,24 @@ cpdef int64_t delta_to_nanoseconds(
206
206
delta,
207
207
NPY_DATETIMEUNIT reso = NPY_FR_ns,
208
208
bint round_ok = True ,
209
- bint allow_year_month = False ,
210
209
) except ? - 1 :
210
+ # Note: this will raise on timedelta64 with Y or M unit
211
+
211
212
cdef:
212
- _Timedelta td
213
213
NPY_DATETIMEUNIT in_reso
214
- int64_t n
214
+ int64_t n, value, factor
215
215
216
216
if is_tick_object(delta):
217
217
n = delta.n
218
218
in_reso = delta._reso
219
- if in_reso == reso:
220
- return n
221
- else :
222
- td = Timedelta._from_value_and_reso(delta.n, reso = in_reso)
223
219
224
220
elif isinstance (delta, _Timedelta):
225
- td = delta
226
221
n = delta.value
227
222
in_reso = delta._reso
228
- if in_reso == reso:
229
- return n
230
223
231
224
elif is_timedelta64_object(delta):
232
225
in_reso = get_datetime64_unit(delta)
233
226
n = get_timedelta64_value(delta)
234
- if in_reso == reso:
235
- return n
236
- else :
237
- # _from_value_and_reso does not support Year, Month, or unit-less,
238
- # so we have special handling if speciifed
239
- try :
240
- td = Timedelta._from_value_and_reso(n, reso = in_reso)
241
- except NotImplementedError :
242
- if allow_year_month:
243
- td64 = ensure_td64ns(delta)
244
- return delta_to_nanoseconds(td64, reso = reso)
245
- else :
246
- raise
247
227
248
228
elif PyDelta_Check(delta):
249
229
in_reso = NPY_DATETIMEUNIT.NPY_FR_us
@@ -256,21 +236,31 @@ cpdef int64_t delta_to_nanoseconds(
256
236
except OverflowError as err:
257
237
raise OutOfBoundsTimedelta(* err.args) from err
258
238
259
- if in_reso == reso:
260
- return n
261
- else :
262
- td = Timedelta._from_value_and_reso(n, reso = in_reso)
263
-
264
239
else :
265
240
raise TypeError (type (delta))
266
241
267
- try :
268
- return td._as_reso(reso, round_ok = round_ok).value
269
- except OverflowError as err:
270
- unit_str = npy_unit_to_abbrev(reso)
271
- raise OutOfBoundsTimedelta(
272
- f" Cannot cast {str(delta)} to unit={unit_str} without overflow."
273
- ) from err
242
+ if reso < in_reso:
243
+ # e.g. ns -> us
244
+ factor = get_conversion_factor(reso, in_reso)
245
+ div, mod = divmod (n, factor)
246
+ if mod > 0 and not round_ok:
247
+ raise ValueError (" Cannot losslessly convert units" )
248
+
249
+ # Note that when mod > 0, we follow np.timedelta64 in always
250
+ # rounding down.
251
+ value = div
252
+ else :
253
+ factor = get_conversion_factor(in_reso, reso)
254
+ try :
255
+ with cython.overflowcheck(True ):
256
+ value = n * factor
257
+ except OverflowError as err:
258
+ unit_str = npy_unit_to_abbrev(reso)
259
+ raise OutOfBoundsTimedelta(
260
+ f" Cannot cast {str(delta)} to unit={unit_str} without overflow."
261
+ ) from err
262
+
263
+ return value
274
264
275
265
276
266
@ cython.overflowcheck (True )
0 commit comments