Skip to content

POC/REF: de-duplicate utc->local code #46246

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

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
move Localizer to tzconversion
  • Loading branch information
jbrockmendel committed Mar 6, 2022
commit a8c56fe5d77441fb5437368786513a2e80052706
22 changes: 0 additions & 22 deletions pandas/_libs/tslibs/timezones.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ from cpython.datetime cimport (
timedelta,
tzinfo,
)
from numpy cimport (
int64_t,
intp_t,
ndarray,
)


cdef tzinfo utc_pytz
Expand All @@ -25,20 +20,3 @@ cdef timedelta get_utcoffset(tzinfo tz, datetime obj)
cdef bint is_fixed_offset(tzinfo tz)

cdef object get_dst_info(tzinfo tz)


cdef class Localizer:
cdef:
tzinfo tz
bint use_utc
bint use_fixed
bint use_tzlocal
bint use_dst
bint use_pytz
ndarray trans
int64_t[:] deltas
int64_t delta
str typ

cdef int64_t prepare1(self, int64_t utc_val)
cdef intp_t* prepare(self, const int64_t[:] stamps)
50 changes: 1 addition & 49 deletions pandas/_libs/tslibs/timezones.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ UTC = pytz.utc
import numpy as np

cimport numpy as cnp
from numpy cimport (
int64_t,
intp_t,
)
from numpy cimport int64_t

cnp.import_array()

Expand Down Expand Up @@ -411,48 +408,3 @@ def tz_standardize(tz: tzinfo) -> tzinfo:
if treat_tz_as_pytz(tz):
return pytz.timezone(str(tz))
return tz


@cython.freelist(16)
cdef class Localizer:
# cdef:
# tzinfo tz
# bint use_utc
# bint use_fixed
# bint use_tzlocal
# bint use_pytz
# bint use_dst
# ndarray trans
# int64_t[:] deltas
# int64_t delta
# str typ

def __cinit__(self, tzinfo tz):
self.tz = tz
if is_utc(tz) or tz is None:
self.use_utc = True
elif is_tzlocal(tz):
self.use_tzlocal = True
else:
trans, deltas, typ = get_dst_info(tz)
self.trans = trans
self.deltas = deltas
self.typ = typ

if typ not in ["pytz", "dateutil"]:
# static/fixed; in this case we know that len(delta) == 1
self.use_fixed = True
self.delta = deltas[0]
else:
self.use_dst = True
if typ == "pytz":
self.use_pytz = True

cdef int64_t prepare1(self, int64_t utc_val):
if self.use_dst:
return self.trans.searchsorted(utc_val, side="right") - 1

cdef intp_t* prepare(self, const int64_t[:] stamps):
if self.use_dst:

return <intp_t*>cnp.PyArray_DATA(self.trans.searchsorted(stamps, side="right") - 1)
20 changes: 18 additions & 2 deletions pandas/_libs/tslibs/tzconversion.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ from cpython.datetime cimport tzinfo
from numpy cimport (
int64_t,
intp_t,
ndarray,
)

from pandas._libs.tslibs.timezones cimport Localizer


cdef int64_t tz_convert_utc_to_tzlocal(
int64_t utc_val, tzinfo tz, bint* fold=*
Expand All @@ -16,4 +15,21 @@ cdef int64_t tz_localize_to_utc_single(
) except? -1


cdef class Localizer:
cdef:
tzinfo tz
bint use_utc
bint use_fixed
bint use_tzlocal
bint use_dst
bint use_pytz
ndarray trans
int64_t[:] deltas
int64_t delta
str typ

cdef int64_t prepare1(self, int64_t utc_val)
cdef intp_t* prepare(self, const int64_t[:] stamps)


cdef int64_t utc_val_to_local_val(Localizer info, int64_t utc_val, intp_t* pos, Py_ssize_t i)
46 changes: 45 additions & 1 deletion pandas/_libs/tslibs/tzconversion.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ from pandas._libs.tslibs.np_datetime cimport (
npy_datetimestruct,
)
from pandas._libs.tslibs.timezones cimport (
Localizer,
get_dst_info,
get_utcoffset,
is_fixed_offset,
Expand Down Expand Up @@ -542,6 +541,51 @@ cdef int64_t _tz_convert_tzlocal_utc(int64_t val, tzinfo tz, bint to_utc=True,
return val + delta


@cython.freelist(16)
cdef class Localizer:
# cdef:
# tzinfo tz
# bint use_utc
# bint use_fixed
# bint use_tzlocal
# bint use_pytz
# bint use_dst
# ndarray trans
# int64_t[:] deltas
# int64_t delta
# str typ

def __cinit__(self, tzinfo tz):
self.tz = tz
if is_utc(tz) or tz is None:
self.use_utc = True
elif is_tzlocal(tz):
self.use_tzlocal = True
else:
trans, deltas, typ = get_dst_info(tz)
self.trans = trans
self.deltas = deltas
self.typ = typ

if typ not in ["pytz", "dateutil"]:
# static/fixed; in this case we know that len(delta) == 1
self.use_fixed = True
self.delta = deltas[0]
else:
self.use_dst = True
if typ == "pytz":
self.use_pytz = True

cdef int64_t prepare1(self, int64_t utc_val):
if self.use_dst:
return self.trans.searchsorted(utc_val, side="right") - 1

cdef intp_t* prepare(self, const int64_t[:] stamps):
if self.use_dst:

return <intp_t*>cnp.PyArray_DATA(self.trans.searchsorted(stamps, side="right") - 1)


# TODO: make this a Localizer method? would require moving tzlocal func
cdef int64_t utc_val_to_local_val(Localizer info, int64_t utc_val, intp_t* pos, Py_ssize_t i):
cdef:
Expand Down
3 changes: 1 addition & 2 deletions pandas/_libs/tslibs/vectorized.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,12 @@ from .offsets cimport BaseOffset
from .period cimport get_period_ordinal
from .timestamps cimport create_timestamp_from_ts
from .timezones cimport (
Localizer,
get_dst_info,
is_tzlocal,
is_utc,
)
from .tzconversion cimport (
tz_convert_utc_to_tzlocal,
Localizer,
utc_val_to_local_val,
)

Expand Down