Skip to content

Commit d08d451

Browse files
authored
REF: de-duplicate precision_from_unit (pandas-dev#51483)
1 parent f26bf27 commit d08d451

File tree

2 files changed

+13
-38
lines changed

2 files changed

+13
-38
lines changed

pandas/_libs/tslibs/conversion.pyx

+11-38
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
@@ -106,10 +107,6 @@ cdef int64_t cast_from_unit(
106107

107108
m, p = precision_from_unit(unit, out_reso)
108109

109-
# just give me the unit back
110-
if ts is None:
111-
return m
112-
113110
if unit in ["Y", "M"]:
114111
if is_float_object(ts) and not ts.is_integer():
115112
# GH#47267 it is clear that 2 "M" corresponds to 1970-02-01,
@@ -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
@@ -162,38 +159,14 @@ cpdef inline (int64_t, int) precision_from_unit(
162159
"""
163160
cdef:
164161
int64_t m
165-
int64_t multiplier
166162
int p
167163
NPY_DATETIMEUNIT reso = abbrev_to_npy_unit(unit)
168164

169-
multiplier = periods_per_second(out_reso)
170-
171-
if reso == NPY_DATETIMEUNIT.NPY_FR_Y:
172-
# each 400 years we have 97 leap years, for an average of 97/400=.2425
173-
# extra days each year. We get 31556952 by writing
174-
# 3600*24*365.2425=31556952
175-
m = multiplier * 31556952
176-
elif reso == NPY_DATETIMEUNIT.NPY_FR_M:
177-
# 2629746 comes from dividing the "Y" case by 12.
178-
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
195-
else:
196-
raise ValueError(f"cannot cast unit {unit}")
165+
if reso == NPY_DATETIMEUNIT.NPY_FR_GENERIC:
166+
reso = NPY_FR_ns
167+
168+
m = get_conversion_factor(reso, out_reso)
169+
197170
p = <int>log10(m) # number of digits in 'm' minus 1
198171
return m, p
199172

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)