Skip to content

Commit 7e19f39

Browse files
authored
REF: de-duplicate precision_from_unit attempt 2 (#51594)
* Remove also-unraisable raising * Restore Y/M cases
1 parent 1c029a8 commit 7e19f39

File tree

3 files changed

+16
-34
lines changed

3 files changed

+16
-34
lines changed

pandas/_libs/tslib.pyx

-4
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ from pandas._libs.tslibs.conversion cimport (
5656
convert_timezone,
5757
get_datetime64_nanos,
5858
parse_pydatetime,
59-
precision_from_unit,
6059
)
6160
from pandas._libs.tslibs.nattype cimport (
6261
NPY_NAT,
@@ -258,7 +257,6 @@ def array_with_unit_to_datetime(
258257
"""
259258
cdef:
260259
Py_ssize_t i, n=len(values)
261-
int64_t mult
262260
bint is_ignore = errors == "ignore"
263261
bint is_coerce = errors == "coerce"
264262
bint is_raise = errors == "raise"
@@ -275,8 +273,6 @@ def array_with_unit_to_datetime(
275273
)
276274
return result, tz
277275

278-
mult, _ = precision_from_unit(unit)
279-
280276
result = np.empty(n, dtype="M8[ns]")
281277
iresult = result.view("i8")
282278

pandas/_libs/tslibs/conversion.pyx

+14-30
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ from pandas._libs.tslibs.np_datetime cimport (
3737
NPY_FR_us,
3838
check_dts_bounds,
3939
convert_reso,
40+
get_conversion_factor,
4041
get_datetime64_unit,
4142
get_datetime64_value,
4243
get_implementation_bounds,
@@ -83,9 +84,9 @@ TD64NS_DTYPE = np.dtype("m8[ns]")
8384
# Unit Conversion Helpers
8485

8586
cdef int64_t cast_from_unit(
86-
object ts,
87-
str unit,
88-
NPY_DATETIMEUNIT out_reso=NPY_FR_ns
87+
object ts,
88+
str unit,
89+
NPY_DATETIMEUNIT out_reso=NPY_FR_ns
8990
) except? -1:
9091
"""
9192
Return a casting of the unit represented to nanoseconds
@@ -104,12 +105,6 @@ cdef int64_t cast_from_unit(
104105
int64_t m
105106
int p
106107

107-
m, p = precision_from_unit(unit, out_reso)
108-
109-
# just give me the unit back
110-
if ts is None:
111-
return m
112-
113108
if unit in ["Y", "M"]:
114109
if is_float_object(ts) and not ts.is_integer():
115110
# GH#47267 it is clear that 2 "M" corresponds to 1970-02-01,
@@ -126,6 +121,8 @@ cdef int64_t cast_from_unit(
126121
dt64obj = np.datetime64(ts, unit)
127122
return get_datetime64_nanos(dt64obj, out_reso)
128123

124+
m, p = precision_from_unit(unit, out_reso)
125+
129126
# cast the unit, multiply base/frac separately
130127
# to avoid precision issues from float -> int
131128
try:
@@ -148,8 +145,8 @@ cdef int64_t cast_from_unit(
148145

149146

150147
cpdef inline (int64_t, int) precision_from_unit(
151-
str unit,
152-
NPY_DATETIMEUNIT out_reso=NPY_DATETIMEUNIT.NPY_FR_ns,
148+
str unit,
149+
NPY_DATETIMEUNIT out_reso=NPY_DATETIMEUNIT.NPY_FR_ns,
153150
):
154151
"""
155152
Return a casting of the unit represented to nanoseconds + the precision
@@ -166,34 +163,21 @@ cpdef inline (int64_t, int) precision_from_unit(
166163
int p
167164
NPY_DATETIMEUNIT reso = abbrev_to_npy_unit(unit)
168165

169-
multiplier = periods_per_second(out_reso)
170-
166+
if reso == NPY_DATETIMEUNIT.NPY_FR_GENERIC:
167+
reso = NPY_DATETIMEUNIT.NPY_FR_ns
171168
if reso == NPY_DATETIMEUNIT.NPY_FR_Y:
172169
# each 400 years we have 97 leap years, for an average of 97/400=.2425
173170
# extra days each year. We get 31556952 by writing
174171
# 3600*24*365.2425=31556952
172+
multiplier = periods_per_second(out_reso)
175173
m = multiplier * 31556952
176174
elif reso == NPY_DATETIMEUNIT.NPY_FR_M:
177175
# 2629746 comes from dividing the "Y" case by 12.
176+
multiplier = periods_per_second(out_reso)
178177
m = multiplier * 2629746
179-
elif reso == NPY_DATETIMEUNIT.NPY_FR_W:
180-
m = multiplier * 3600 * 24 * 7
181-
elif reso == NPY_DATETIMEUNIT.NPY_FR_D:
182-
m = multiplier * 3600 * 24
183-
elif reso == NPY_DATETIMEUNIT.NPY_FR_h:
184-
m = multiplier * 3600
185-
elif reso == NPY_DATETIMEUNIT.NPY_FR_m:
186-
m = multiplier * 60
187-
elif reso == NPY_DATETIMEUNIT.NPY_FR_s:
188-
m = multiplier
189-
elif reso == NPY_DATETIMEUNIT.NPY_FR_ms:
190-
m = multiplier // 1_000
191-
elif reso == NPY_DATETIMEUNIT.NPY_FR_us:
192-
m = multiplier // 1_000_000
193-
elif reso == NPY_DATETIMEUNIT.NPY_FR_ns or reso == NPY_DATETIMEUNIT.NPY_FR_GENERIC:
194-
m = multiplier // 1_000_000_000
195178
else:
196-
raise ValueError(f"cannot cast unit {unit}")
179+
m = get_conversion_factor(reso, out_reso)
180+
197181
p = <int>log10(m) # number of digits in 'm' minus 1
198182
return m, p
199183

pandas/_libs/tslibs/np_datetime.pyx

+2
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,8 @@ cdef int64_t get_conversion_factor(
571571
return 1000 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_fs, to_unit)
572572
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_fs:
573573
return 1000 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_as, to_unit)
574+
else:
575+
raise ValueError("Converting from M or Y units is not supported.")
574576

575577

576578
cdef int64_t convert_reso(

0 commit comments

Comments
 (0)