Skip to content

REF: implement tz_localize_to_utc_single #35108

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
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
7 changes: 3 additions & 4 deletions pandas/_libs/tslib.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ from pandas._libs.tslibs.timezones cimport (
get_dst_info,
is_utc,
is_tzlocal,
utc_pytz as UTC,
)
from pandas._libs.tslibs.conversion cimport (
_TSObject,
Expand All @@ -67,8 +66,8 @@ from pandas._libs.tslibs.timestamps cimport create_timestamp_from_ts, _Timestamp
from pandas._libs.tslibs.timestamps import Timestamp

from pandas._libs.tslibs.tzconversion cimport (
tz_convert_single,
tz_convert_utc_to_tzlocal,
tz_localize_to_utc_single,
)

# Note: this is the only non-tslibs intra-pandas dependency here
Expand Down Expand Up @@ -269,7 +268,7 @@ def _test_parse_iso8601(ts: str):
check_dts_bounds(&obj.dts)
if out_local == 1:
obj.tzinfo = pytz.FixedOffset(out_tzoffset)
obj.value = tz_convert_single(obj.value, obj.tzinfo, UTC)
obj.value = tz_localize_to_utc_single(obj.value, obj.tzinfo)
return Timestamp(obj.value, tz=obj.tzinfo)
else:
return Timestamp(obj.value)
Expand Down Expand Up @@ -727,7 +726,7 @@ cpdef array_to_datetime(
# dateutil.tz.tzoffset objects
out_tzoffset_vals.add(out_tzoffset * 60.)
tz = pytz.FixedOffset(out_tzoffset)
value = tz_convert_single(value, tz, UTC)
value = tz_localize_to_utc_single(value, tz)
out_local = 0
out_tzoffset = 0
else:
Expand Down
9 changes: 4 additions & 5 deletions pandas/_libs/tslibs/conversion.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,9 @@ from pandas._libs.tslibs.nattype cimport (
c_nat_strings as nat_strings,
)

from pandas._libs.tslibs.tzconversion import tz_localize_to_utc
from pandas._libs.tslibs.tzconversion cimport (
tz_convert_utc_to_tzlocal,
tz_convert_single,
tz_localize_to_utc_single,
)

# ----------------------------------------------------------------------
Expand Down Expand Up @@ -470,7 +469,7 @@ cdef _TSObject _create_tsobject_tz_using_offset(npy_datetimestruct dts,
value = dtstruct_to_dt64(&dts)
obj.dts = dts
obj.tzinfo = pytz.FixedOffset(tzoffset)
obj.value = tz_convert_single(value, obj.tzinfo, UTC)
obj.value = tz_localize_to_utc_single(value, obj.tzinfo)
if tz is None:
check_overflows(obj)
return obj
Expand Down Expand Up @@ -555,8 +554,8 @@ cdef _TSObject _convert_str_to_tsobject(object ts, tzinfo tz, object unit,
ts = dtstruct_to_dt64(&dts)
if tz is not None:
# shift for _localize_tso
ts = tz_localize_to_utc(np.array([ts], dtype='i8'), tz,
ambiguous='raise')[0]
ts = tz_localize_to_utc_single(ts, tz,
ambiguous="raise")

except OutOfBoundsDatetime:
# GH#19382 for just-barely-OutOfBounds falling back to dateutil
Expand Down
12 changes: 7 additions & 5 deletions pandas/_libs/tslibs/timestamps.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ from pandas._libs.tslibs.timezones cimport (
is_utc, maybe_get_tz, treat_tz_as_pytz, utc_pytz as UTC,
get_timezone, tz_compare,
)
from pandas._libs.tslibs.tzconversion cimport tz_convert_single
from pandas._libs.tslibs.tzconversion import tz_localize_to_utc
from pandas._libs.tslibs.tzconversion cimport (
tz_convert_single,
tz_localize_to_utc_single,
)

# ----------------------------------------------------------------------
# Constants
Expand Down Expand Up @@ -1299,9 +1301,9 @@ default 'raise'
tz = maybe_get_tz(tz)
if not isinstance(ambiguous, str):
ambiguous = [ambiguous]
value = tz_localize_to_utc(np.array([self.value], dtype='i8'), tz,
ambiguous=ambiguous,
nonexistent=nonexistent)[0]
value = tz_localize_to_utc_single(self.value, tz,
ambiguous=ambiguous,
nonexistent=nonexistent)
return Timestamp(value, tz=tz, freq=self.freq)
else:
if tz is None:
Expand Down
3 changes: 3 additions & 0 deletions pandas/_libs/tslibs/tzconversion.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ from numpy cimport int64_t

cdef int64_t tz_convert_utc_to_tzlocal(int64_t utc_val, tzinfo tz, bint* fold=*)
cpdef int64_t tz_convert_single(int64_t val, tzinfo tz1, tzinfo tz2)
cdef int64_t tz_localize_to_utc_single(
int64_t val, tzinfo tz, object ambiguous=*, object nonexistent=*
) except? -1
42 changes: 40 additions & 2 deletions pandas/_libs/tslibs/tzconversion.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,48 @@ from pandas._libs.tslibs.ccalendar cimport DAY_NANOS, HOUR_NANOS
from pandas._libs.tslibs.nattype cimport NPY_NAT
from pandas._libs.tslibs.np_datetime cimport (
npy_datetimestruct, dt64_to_dtstruct)
from pandas._libs.tslibs.timezones cimport get_dst_info, is_tzlocal, is_utc
from pandas._libs.tslibs.timezones cimport (
get_dst_info,
get_utcoffset,
is_fixed_offset,
is_tzlocal,
is_utc,
)


cdef int64_t tz_localize_to_utc_single(
int64_t val, tzinfo tz, object ambiguous=None, object nonexistent=None,
) except? -1:
"""See tz_localize_to_utc.__doc__"""
cdef:
int64_t delta
int64_t[:] deltas

if val == NPY_NAT:
return val

elif is_utc(tz) or tz is None:
return val

elif is_tzlocal(tz):
return _tz_convert_tzlocal_utc(val, tz, to_utc=True)

elif is_fixed_offset(tz):
# TODO: in this case we should be able to use get_utcoffset,
# that returns None for e.g. 'dateutil//usr/share/zoneinfo/Etc/GMT-9'
_, deltas, _ = get_dst_info(tz)
delta = deltas[0]
return val - delta

else:
return tz_localize_to_utc(
np.array([val], dtype="i8"),
tz,
ambiguous=ambiguous,
nonexistent=nonexistent,
)[0]


# TODO: cdef scalar version to call from convert_str_to_tsobject
@cython.boundscheck(False)
@cython.wraparound(False)
def tz_localize_to_utc(ndarray[int64_t] vals, tzinfo tz, object ambiguous=None,
Expand Down