Skip to content

Commit 887d2c4

Browse files
authored
Revert "REF: de-duplicate precision_from_unit" (#51584)
Revert "REF: de-duplicate precision_from_unit (#51483)" This reverts commit d08d451.
1 parent fb80674 commit 887d2c4

File tree

2 files changed

+38
-13
lines changed

2 files changed

+38
-13
lines changed

pandas/_libs/tslibs/conversion.pyx

+38-11
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ from pandas._libs.tslibs.np_datetime cimport (
3737
NPY_FR_us,
3838
check_dts_bounds,
3939
convert_reso,
40-
get_conversion_factor,
4140
get_datetime64_unit,
4241
get_datetime64_value,
4342
get_implementation_bounds,
@@ -84,9 +83,9 @@ TD64NS_DTYPE = np.dtype("m8[ns]")
8483
# Unit Conversion Helpers
8584

8685
cdef int64_t cast_from_unit(
87-
object ts,
88-
str unit,
89-
NPY_DATETIMEUNIT out_reso=NPY_FR_ns
86+
object ts,
87+
str unit,
88+
NPY_DATETIMEUNIT out_reso=NPY_FR_ns
9089
) except? -1:
9190
"""
9291
Return a casting of the unit represented to nanoseconds
@@ -107,6 +106,10 @@ cdef int64_t cast_from_unit(
107106

108107
m, p = precision_from_unit(unit, out_reso)
109108

109+
# just give me the unit back
110+
if ts is None:
111+
return m
112+
110113
if unit in ["Y", "M"]:
111114
if is_float_object(ts) and not ts.is_integer():
112115
# GH#47267 it is clear that 2 "M" corresponds to 1970-02-01,
@@ -145,8 +148,8 @@ cdef int64_t cast_from_unit(
145148

146149

147150
cpdef inline (int64_t, int) precision_from_unit(
148-
str unit,
149-
NPY_DATETIMEUNIT out_reso=NPY_DATETIMEUNIT.NPY_FR_ns,
151+
str unit,
152+
NPY_DATETIMEUNIT out_reso=NPY_DATETIMEUNIT.NPY_FR_ns,
150153
):
151154
"""
152155
Return a casting of the unit represented to nanoseconds + the precision
@@ -159,14 +162,38 @@ cpdef inline (int64_t, int) precision_from_unit(
159162
"""
160163
cdef:
161164
int64_t m
165+
int64_t multiplier
162166
int p
163167
NPY_DATETIMEUNIT reso = abbrev_to_npy_unit(unit)
164168

165-
if reso == NPY_DATETIMEUNIT.NPY_FR_GENERIC:
166-
reso = NPY_FR_ns
167-
168-
m = get_conversion_factor(reso, out_reso)
169-
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}")
170197
p = <int>log10(m) # number of digits in 'm' minus 1
171198
return m, p
172199

pandas/_libs/tslibs/np_datetime.pyx

-2
Original file line numberDiff line numberDiff line change
@@ -571,8 +571,6 @@ 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.")
576574

577575

578576
cdef int64_t convert_reso(

0 commit comments

Comments
 (0)