Skip to content

Revert "REF: de-duplicate precision_from_unit" #51584

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 38 additions & 11 deletions pandas/_libs/tslibs/conversion.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ from pandas._libs.tslibs.np_datetime cimport (
NPY_FR_us,
check_dts_bounds,
convert_reso,
get_conversion_factor,
get_datetime64_unit,
get_datetime64_value,
get_implementation_bounds,
Expand Down Expand Up @@ -84,9 +83,9 @@ TD64NS_DTYPE = np.dtype("m8[ns]")
# Unit Conversion Helpers

cdef int64_t cast_from_unit(
object ts,
str unit,
NPY_DATETIMEUNIT out_reso=NPY_FR_ns
object ts,
str unit,
NPY_DATETIMEUNIT out_reso=NPY_FR_ns
) except? -1:
"""
Return a casting of the unit represented to nanoseconds
Expand All @@ -107,6 +106,10 @@ cdef int64_t cast_from_unit(

m, p = precision_from_unit(unit, out_reso)

# just give me the unit back
if ts is None:
return m

if unit in ["Y", "M"]:
if is_float_object(ts) and not ts.is_integer():
# GH#47267 it is clear that 2 "M" corresponds to 1970-02-01,
Expand Down Expand Up @@ -145,8 +148,8 @@ cdef int64_t cast_from_unit(


cpdef inline (int64_t, int) precision_from_unit(
str unit,
NPY_DATETIMEUNIT out_reso=NPY_DATETIMEUNIT.NPY_FR_ns,
str unit,
NPY_DATETIMEUNIT out_reso=NPY_DATETIMEUNIT.NPY_FR_ns,
):
"""
Return a casting of the unit represented to nanoseconds + the precision
Expand All @@ -159,14 +162,38 @@ cpdef inline (int64_t, int) precision_from_unit(
"""
cdef:
int64_t m
int64_t multiplier
int p
NPY_DATETIMEUNIT reso = abbrev_to_npy_unit(unit)

if reso == NPY_DATETIMEUNIT.NPY_FR_GENERIC:
reso = NPY_FR_ns

m = get_conversion_factor(reso, out_reso)

multiplier = periods_per_second(out_reso)

if reso == NPY_DATETIMEUNIT.NPY_FR_Y:
# each 400 years we have 97 leap years, for an average of 97/400=.2425
# extra days each year. We get 31556952 by writing
# 3600*24*365.2425=31556952
m = multiplier * 31556952
elif reso == NPY_DATETIMEUNIT.NPY_FR_M:
# 2629746 comes from dividing the "Y" case by 12.
m = multiplier * 2629746
elif reso == NPY_DATETIMEUNIT.NPY_FR_W:
m = multiplier * 3600 * 24 * 7
elif reso == NPY_DATETIMEUNIT.NPY_FR_D:
m = multiplier * 3600 * 24
elif reso == NPY_DATETIMEUNIT.NPY_FR_h:
m = multiplier * 3600
elif reso == NPY_DATETIMEUNIT.NPY_FR_m:
m = multiplier * 60
elif reso == NPY_DATETIMEUNIT.NPY_FR_s:
m = multiplier
elif reso == NPY_DATETIMEUNIT.NPY_FR_ms:
m = multiplier // 1_000
elif reso == NPY_DATETIMEUNIT.NPY_FR_us:
m = multiplier // 1_000_000
elif reso == NPY_DATETIMEUNIT.NPY_FR_ns or reso == NPY_DATETIMEUNIT.NPY_FR_GENERIC:
m = multiplier // 1_000_000_000
else:
raise ValueError(f"cannot cast unit {unit}")
p = <int>log10(m) # number of digits in 'm' minus 1
return m, p

Expand Down
2 changes: 0 additions & 2 deletions pandas/_libs/tslibs/np_datetime.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -571,8 +571,6 @@ cdef int64_t get_conversion_factor(
return 1000 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_fs, to_unit)
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_fs:
return 1000 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_as, to_unit)
else:
raise ValueError("Converting from M or Y units is not supported.")


cdef int64_t convert_reso(
Expand Down