Skip to content

REF: re-use existing conversion functions #34625

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 4 commits into from
Jun 8, 2020
Merged
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
67 changes: 32 additions & 35 deletions pandas/_libs/tslibs/period.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -763,10 +763,9 @@ cdef int64_t get_period_ordinal(npy_datetimestruct *dts, int freq) nogil:
period_ordinal : int64_t
"""
cdef:
int64_t unix_date, seconds, delta
int64_t weeks
int64_t day_adj
int64_t unix_date
int freq_group, fmonth, mdiff
NPY_DATETIMEUNIT unit

freq_group = get_freq_group(freq)

Expand All @@ -789,44 +788,42 @@ cdef int64_t get_period_ordinal(npy_datetimestruct *dts, int freq) nogil:
mdiff = dts.month - fmonth + 12
return (dts.year - 1970) * 4 + (mdiff - 1) // 3

elif freq == FR_MTH:
return (dts.year - 1970) * 12 + dts.month - 1

unix_date = npy_datetimestruct_to_datetime(NPY_FR_D, dts)

if freq >= FR_SEC:
seconds = unix_date * 86400 + dts.hour * 3600 + dts.min * 60 + dts.sec

if freq == FR_MS:
return seconds * 1000 + dts.us // 1000

elif freq == FR_US:
return seconds * 1000000 + dts.us

elif freq == FR_NS:
return (seconds * 1000000000 +
dts.us * 1000 + dts.ps // 1000)
elif freq_group == FR_WK:
unix_date = npy_datetimestruct_to_datetime(NPY_FR_D, dts)
return unix_date_to_week(unix_date, freq - FR_WK)

else:
return seconds
elif freq == FR_BUS:
unix_date = npy_datetimestruct_to_datetime(NPY_FR_D, dts)
return DtoB(dts, 0, unix_date)

elif freq == FR_MIN:
return unix_date * 1440 + dts.hour * 60 + dts.min
unit = get_unit(freq)
return npy_datetimestruct_to_datetime(unit, dts)

elif freq == FR_HR:
return unix_date * 24 + dts.hour

cdef NPY_DATETIMEUNIT get_unit(int freq) nogil:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could alternately just be an enum right? OK as is just suggesting as possible easier solution

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what you're suggesting is something like:

cdef enum FreqGroup:
    FR_MTH = NPY_DATETIMEUNIT.NPY_FR_M
    FR_DAY = NPY_DATETIMEUNIT.NPY_FR_D
    [...]

LMK if you have something else in mind.

The trouble with that is that we currently actually use the values for FR_FOO directly, and this would change those.

There are a bunch of near-duplicate enum-like codes floating around that i do want to de-duplicate. #34588 makes FreqGroup an enum, and after #34587 im hoping we can de-duplicate FreqGroup with Resolution.

"""
Convert the freq to the corresponding NPY_DATETIMEUNIT to pass
to npy_datetimestruct_to_datetime.
"""
if freq == FR_MTH:
return NPY_DATETIMEUNIT.NPY_FR_M
elif freq == FR_DAY:
return unix_date

return NPY_DATETIMEUNIT.NPY_FR_D
elif freq == FR_HR:
return NPY_DATETIMEUNIT.NPY_FR_h
elif freq == FR_MIN:
return NPY_DATETIMEUNIT.NPY_FR_m
elif freq == FR_SEC:
return NPY_DATETIMEUNIT.NPY_FR_s
elif freq == FR_MS:
return NPY_DATETIMEUNIT.NPY_FR_ms
elif freq == FR_US:
return NPY_DATETIMEUNIT.NPY_FR_us
elif freq == FR_NS:
return NPY_DATETIMEUNIT.NPY_FR_ns
elif freq == FR_UND:
return unix_date

elif freq == FR_BUS:
return DtoB(dts, 0, unix_date)

elif freq_group == FR_WK:
return unix_date_to_week(unix_date, freq - FR_WK)
# Default to Day
return NPY_DATETIMEUNIT.NPY_FR_D


cdef void get_date_info(int64_t ordinal, int freq, npy_datetimestruct *dts) nogil:
Expand Down