Skip to content

Implement _tz_convert_tzlocal_utc for de-duplication #21727

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
Jul 4, 2018
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
59 changes: 20 additions & 39 deletions pandas/_libs/tslibs/conversion.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ cdef inline void localize_tso(_TSObject obj, tzinfo tz):
elif obj.value == NPY_NAT:
pass
elif is_tzlocal(tz):
local_val = tz_convert_utc_to_tzlocal(obj.value, tz)
local_val = _tz_convert_tzlocal_utc(obj.value, tz, to_utc=False)
dt64_to_dtstruct(local_val, &obj.dts)
else:
# Adjust datetime64 timestamp, recompute datetimestruct
Expand Down Expand Up @@ -608,32 +608,33 @@ cpdef inline datetime localize_pydatetime(datetime dt, object tz):
# ----------------------------------------------------------------------
# Timezone Conversion

cdef inline int64_t tz_convert_tzlocal_to_utc(int64_t val, tzinfo tz):
cdef inline int64_t _tz_convert_tzlocal_utc(int64_t val, tzinfo tz,
bint to_utc=True):
Copy link
Contributor

Choose a reason for hiding this comment

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

looks good. can you add what this function does in doc-string. and mark as this is private.

Copy link
Member Author

Choose a reason for hiding this comment

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

Mind if I put the docsting in the follow-up? There’s a couple more coming up in the next few hours.

Copy link
Contributor

Choose a reason for hiding this comment

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

sure

"""
Parameters
----------
val : int64_t
tz : tzinfo
to_utc : bint
True if converting tzlocal _to_ UTC, False if going the other direction

Returns
-------
utc_date : int64_t

See Also
--------
tz_convert_utc_to_tzlocal
result : int64_t
"""
cdef:
pandas_datetimestruct dts
int64_t utc_date, delta
int64_t result, delta
datetime dt

dt64_to_dtstruct(val, &dts)
dt = datetime(dts.year, dts.month, dts.day, dts.hour,
dts.min, dts.sec, dts.us, tz)
delta = int(get_utcoffset(tz, dt).total_seconds()) * 1000000000
utc_date = val - delta
return utc_date

if not to_utc:
return val + delta
return val - delta


cdef inline int64_t tz_convert_utc_to_tzlocal(int64_t utc_val, tzinfo tz):
Expand All @@ -646,27 +647,8 @@ cdef inline int64_t tz_convert_utc_to_tzlocal(int64_t utc_val, tzinfo tz):
Returns
-------
local_val : int64_t

See Also
--------
tz_convert_tzlocal_to_utc

Notes
-----
The key difference between this and tz_convert_tzlocal_to_utc is a
an addition flipped to a subtraction in the last line.
"""
cdef:
pandas_datetimestruct dts
int64_t local_val, delta
datetime dt

dt64_to_dtstruct(utc_val, &dts)
dt = datetime(dts.year, dts.month, dts.day, dts.hour,
dts.min, dts.sec, dts.us, tz)
delta = int(get_utcoffset(tz, dt).total_seconds()) * 1000000000
local_val = utc_val + delta
return local_val
return _tz_convert_tzlocal_utc(utc_val, tz, to_utc=False)


cpdef int64_t tz_convert_single(int64_t val, object tz1, object tz2):
Expand Down Expand Up @@ -699,7 +681,7 @@ cpdef int64_t tz_convert_single(int64_t val, object tz1, object tz2):

# Convert to UTC
if is_tzlocal(tz1):
utc_date = tz_convert_tzlocal_to_utc(val, tz1)
utc_date = _tz_convert_tzlocal_utc(val, tz1, to_utc=True)
elif get_timezone(tz1) != 'UTC':
trans, deltas, typ = get_dst_info(tz1)
pos = trans.searchsorted(val, side='right') - 1
Expand All @@ -713,7 +695,7 @@ cpdef int64_t tz_convert_single(int64_t val, object tz1, object tz2):
if get_timezone(tz2) == 'UTC':
return utc_date
elif is_tzlocal(tz2):
return tz_convert_utc_to_tzlocal(utc_date, tz2)
return _tz_convert_tzlocal_utc(utc_date, tz2, to_utc=False)

# Convert UTC to other timezone
trans, deltas, typ = get_dst_info(tz2)
Expand Down Expand Up @@ -762,7 +744,7 @@ def tz_convert(ndarray[int64_t] vals, object tz1, object tz2):
if v == NPY_NAT:
utc_dates[i] = NPY_NAT
else:
utc_dates[i] = tz_convert_tzlocal_to_utc(v, tz1)
utc_dates[i] = _tz_convert_tzlocal_utc(v, tz1, to_utc=True)
else:
trans, deltas, typ = get_dst_info(tz1)

Expand Down Expand Up @@ -797,7 +779,7 @@ def tz_convert(ndarray[int64_t] vals, object tz1, object tz2):
if v == NPY_NAT:
result[i] = NPY_NAT
else:
result[i] = tz_convert_utc_to_tzlocal(v, tz2)
result[i] = _tz_convert_tzlocal_utc(v, tz2, to_utc=False)
return result

# Convert UTC to other timezone
Expand All @@ -809,7 +791,7 @@ def tz_convert(ndarray[int64_t] vals, object tz1, object tz2):
return result

# if all NaT, return all NaT
tt = utc_dates[utc_dates!=NPY_NAT]
tt = utc_dates[utc_dates != NPY_NAT]
if not len(tt):
return utc_dates

Expand Down Expand Up @@ -874,7 +856,7 @@ def tz_localize_to_utc(ndarray[int64_t] vals, object tz, object ambiguous=None,
if is_tzlocal(tz):
for i in range(n):
v = vals[i]
result[i] = tz_convert_tzlocal_to_utc(v, tz)
result[i] = _tz_convert_tzlocal_utc(v, tz, to_utc=True)
return result

if is_string_object(ambiguous):
Expand Down Expand Up @@ -1116,7 +1098,7 @@ cdef ndarray[int64_t] _normalize_local(ndarray[int64_t] stamps, object tz):
if stamps[i] == NPY_NAT:
result[i] = NPY_NAT
continue
local_val = tz_convert_utc_to_tzlocal(stamps[i], tz)
local_val = _tz_convert_tzlocal_utc(stamps[i], tz, to_utc=False)
dt64_to_dtstruct(local_val, &dts)
result[i] = _normalized_stamp(&dts)
else:
Expand Down Expand Up @@ -1195,7 +1177,7 @@ def is_date_array_normalized(ndarray[int64_t] stamps, tz=None):
return False
elif is_tzlocal(tz):
for i in range(n):
local_val = tz_convert_utc_to_tzlocal(stamps[i], tz)
local_val = _tz_convert_tzlocal_utc(stamps[i], tz, to_utc=False)
dt64_to_dtstruct(local_val, &dts)
if (dts.hour + dts.min + dts.sec + dts.us) > 0:
return False
Expand All @@ -1205,7 +1187,6 @@ def is_date_array_normalized(ndarray[int64_t] stamps, tz=None):
for i in range(n):
# Adjust datetime64 timestamp, recompute datetimestruct
pos = trans.searchsorted(stamps[i]) - 1
inf = tz._transition_info[pos]
Copy link
Member Author

Choose a reason for hiding this comment

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

unrelated to the rest of the PR


dt64_to_dtstruct(stamps[i] + deltas[pos], &dts)
if (dts.hour + dts.min + dts.sec + dts.us) > 0:
Expand Down