@@ -41,6 +41,7 @@ from pandas._libs.tslibs.conversion cimport (
4141 cast_from_unit,
4242 convert_datetime_to_tsobject,
4343 get_datetime64_nanos,
44+ precision_from_unit,
4445)
4546from pandas._libs.tslibs.nattype cimport (
4647 NPY_NAT,
@@ -205,6 +206,7 @@ def array_with_unit_to_datetime(
205206 cdef:
206207 Py_ssize_t i, j, n= len (values)
207208 int64_t m
209+ int prec = 0
208210 ndarray[float64_t] fvalues
209211 bint is_ignore = errors== ' ignore'
210212 bint is_coerce = errors== ' coerce'
@@ -217,38 +219,48 @@ def array_with_unit_to_datetime(
217219
218220 assert is_ignore or is_coerce or is_raise
219221
220- if unit == ' ns ' :
221- if issubclass (values.dtype.type, np.integer):
222- result = values.astype(' M8[ns]' )
222+ if unit == " ns " :
223+ if issubclass (values.dtype.type, ( np.integer, np.float_) ):
224+ result = values.astype(" M8[ns]" , copy = False )
223225 else :
224226 result, tz = array_to_datetime(values.astype(object ), errors = errors)
225227 return result, tz
226228
227- m = cast_from_unit( None , unit)
229+ m, p = precision_from_unit( unit)
228230
229231 if is_raise:
230-
231- # try a quick conversion to i8
232+ # try a quick conversion to i8/f8
232233 # if we have nulls that are not type-compat
233234 # then need to iterate
234- if values.dtype.kind == " i " :
235- # Note: this condition makes the casting="same_kind" redundant
236- iresult = values.astype(' i8 ' , casting = ' same_kind ' , copy = False )
237- # fill by comparing to NPY_NAT constant
235+
236+ if values.dtype.kind == " i " or values.dtype.kind == " f " :
237+ iresult = values.astype(" i8 " , copy = False )
238+ # fill missing values by comparing to NPY_NAT
238239 mask = iresult == NPY_NAT
239240 iresult[mask] = 0
240- fvalues = iresult.astype(' f8 ' ) * m
241+ fvalues = iresult.astype(" f8 " ) * m
241242 need_to_iterate = False
242243
243- # check the bounds
244244 if not need_to_iterate:
245-
246- if ((fvalues < Timestamp.min.value).any()
247- or (fvalues > Timestamp.max.value).any()):
245+ # check the bounds
246+ if (fvalues < Timestamp.min.value).any() or (
247+ (fvalues > Timestamp.max.value).any()
248+ ):
248249 raise OutOfBoundsDatetime(f" cannot convert input with unit '{unit}'" )
249- result = (iresult * m).astype(' M8[ns]' )
250- iresult = result.view(' i8' )
250+
251+ if values.dtype.kind == " i" :
252+ result = (iresult * m).astype(" M8[ns]" )
253+
254+ elif values.dtype.kind == " f" :
255+ fresult = (values * m).astype(" f8" )
256+ fresult[mask] = 0
257+ if prec:
258+ fresult = round (fresult, prec)
259+ result = fresult.astype(" M8[ns]" , copy = False )
260+
261+ iresult = result.view(" i8" )
251262 iresult[mask] = NPY_NAT
263+
252264 return result, tz
253265
254266 result = np.empty(n, dtype = ' M8[ns]' )
0 commit comments