-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
WIP: multi-timezone handling for array_to_datetime #24006
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
Changes from 11 commits
13336d9
4b80797
f0dccc7
1b36e6f
9d42d97
515a23b
edc177d
a2a01c9
1c6a8ee
9677010
cf8b4cc
ec35002
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -114,7 +114,7 @@ def _p_tz_cache_key(tz): | |
dst_cache = {} | ||
|
||
|
||
cdef inline object tz_cache_key(object tz): | ||
cpdef object tz_cache_key(object tz): | ||
""" | ||
Return the key in the cache for the timezone info object or None | ||
if unknown. | ||
|
@@ -158,8 +158,22 @@ cdef get_utcoffset(tzinfo, obj): | |
return tzinfo.utcoffset(obj) | ||
|
||
|
||
cdef get_fixed_offset_total_seconds(tzinfo tz): | ||
""" | ||
For compat between pytz.FixedOffset, dateutil.tz.tzoffset | ||
""" | ||
if hasattr(tz, "_offset"): | ||
# dateutil, pytz | ||
return tz._offset.total_seconds() | ||
else: | ||
# TODO: Will it ever want an actual datetime? | ||
return tz.utcoffset(None) | ||
|
||
|
||
cdef inline bint is_fixed_offset(object tz): | ||
if treat_tz_as_dateutil(tz): | ||
if tz is None: | ||
return 0 | ||
elif treat_tz_as_dateutil(tz): | ||
if len(tz._trans_idx) == 0 and len(tz._trans_list) == 0: | ||
return 1 | ||
else: | ||
|
@@ -170,7 +184,9 @@ cdef inline bint is_fixed_offset(object tz): | |
return 1 | ||
else: | ||
return 0 | ||
return 1 | ||
if not isinstance(tz, tzinfo): | ||
return 0 | ||
return 1 # TODO: No! | ||
|
||
|
||
cdef object get_utc_trans_times_from_dateutil_tz(object tz): | ||
|
@@ -295,7 +311,7 @@ def infer_tzinfo(start, end): | |
return tz | ||
|
||
|
||
cpdef bint tz_compare(object start, object end): | ||
cpdef bint tz_compare(object start, object end) except? -1: | ||
""" | ||
Compare string representations of timezones | ||
|
||
|
@@ -321,6 +337,10 @@ cpdef bint tz_compare(object start, object end): | |
|
||
""" | ||
# GH 18523 | ||
if is_fixed_offset(start) and is_fixed_offset(end): | ||
start_seconds = get_fixed_offset_total_seconds(start) | ||
end_seconds = get_fixed_offset_total_seconds(end) | ||
return start_seconds == end_seconds | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mroeschke @jreback are we in agreement that two FixedOffsets of matching length should be considered equal? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this seems reasonsable can u just compare the start == end ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok that makes sense There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds reasonable. If a user passes both a |
||
return get_timezone(start) == get_timezone(end) | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -877,7 +877,7 @@ def maybe_infer_to_datetimelike(value, convert_dates=False): | |
return value | ||
|
||
shape = v.shape | ||
if not v.ndim == 1: | ||
if v.ndim != 1: | ||
v = v.ravel() | ||
|
||
if not len(v): | ||
|
@@ -887,26 +887,18 @@ def try_datetime(v): | |
# safe coerce to datetime64 | ||
try: | ||
# GH19671 | ||
v = tslib.array_to_datetime(v, | ||
require_iso8601=True, | ||
errors='raise')[0] | ||
except ValueError: | ||
|
||
# we might have a sequence of the same-datetimes with tz's | ||
# if so coerce to a DatetimeIndex; if they are not the same, | ||
# then these stay as object dtype, xref GH19671 | ||
try: | ||
from pandas._libs.tslibs import conversion | ||
from pandas import DatetimeIndex | ||
|
||
values, tz = conversion.datetime_to_datetime64(v) | ||
return DatetimeIndex(values).tz_localize( | ||
'UTC').tz_convert(tz=tz) | ||
except (ValueError, TypeError): | ||
pass | ||
|
||
v, inferred_tz = tslib.array_to_datetime(v, | ||
require_iso8601=True, | ||
errors='raise') | ||
except Exception: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this still needed? |
||
pass | ||
else: | ||
if inferred_tz is not None: | ||
# TODO: de-duplicate with to_datetime | ||
from pandas import DatetimeIndex | ||
dti = DatetimeIndex(v).tz_localize('UTC') | ||
return dti.tz_convert(tz=inferred_tz) | ||
# TODO: possibly reshape? | ||
|
||
return v.reshape(shape) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you type & add a doc-string