-
-
Notifications
You must be signed in to change notification settings - Fork 18.5k
REF: de-duplicate DST tzconversion code #35077
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 41 commits
4b8c4fb
d8bffdd
fc1ad75
998341e
8114413
907f9c4
addf931
b2154d4
9bcccc0
bb7e60d
407f266
5adca21
69bfb80
13244c8
c0f8b34
8620905
3605695
a0eb787
c8fcc19
db71af5
e47e490
7f8c717
e21cd6a
9a47096
d6dce1a
0dbd8ac
f9514b4
e198dbd
681f5b8
e93b961
52af5e1
26d0d3a
3b220fb
3c1bf60
a70ce3f
2478ec3
21cbfc2
2aa256a
7669dc2
2bfb9df
3dd2957
b31c40e
8b2e9a3
e5b73c7
184e188
b974ec7
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 |
---|---|---|
@@ -0,0 +1,50 @@ | ||
""" | ||
ipython analogue: | ||
|
||
tr = TimeResolution() | ||
mi = pd.MultiIndex.from_product(tr.params[:-1] + ([str(x) for x in tr.params[-1]],)) | ||
df = pd.DataFrame(np.nan, index=mi, columns=["mean", "stdev"]) | ||
|
||
for unit in tr.params[0]: | ||
for size in tr.params[1]: | ||
for tz in tr.params[2]: | ||
tr.setup(unit, size, tz) | ||
key = (unit, size, str(tz)) | ||
print(key) | ||
|
||
val = %timeit -o tr.time_get_resolution(unit, size, tz) | ||
|
||
df.loc[key] = (val.average, val.stdev) | ||
|
||
""" | ||
from datetime import timedelta, timezone | ||
|
||
from dateutil.tz import gettz, tzlocal | ||
import numpy as np | ||
import pytz | ||
|
||
from pandas._libs.tslibs.resolution import get_resolution | ||
|
||
|
||
class TimeResolution: | ||
params = ( | ||
["D", "h", "m", "s", "us", "ns"], | ||
[1, 100, 10 ** 4, 10 ** 6], | ||
[ | ||
None, | ||
timezone.utc, | ||
timezone(timedelta(minutes=60)), | ||
pytz.timezone("US/Pacific"), | ||
gettz("Asia/Tokyo"), | ||
tzlocal(), | ||
], | ||
) | ||
param_names = ["unit", "size", "tz"] | ||
|
||
def setup(self, unit, size, tz): | ||
arr = np.random.randint(0, 10, size=size, dtype="i8") | ||
arr = arr.view(f"M8[{unit}]").astype("M8[ns]").view("i8") | ||
self.i8data = arr | ||
|
||
def time_get_resolution(self, unit, size, tz): | ||
get_resolution(self.i8data, tz) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,14 @@ | ||
from cpython.datetime cimport tzinfo | ||
|
||
import numpy as np | ||
from numpy cimport ndarray, int64_t, int32_t | ||
from numpy cimport ndarray, int64_t, int32_t, intp_t | ||
|
||
from pandas._libs.tslibs.util cimport get_nat | ||
|
||
from pandas._libs.tslibs.dtypes import Resolution | ||
from pandas._libs.tslibs.np_datetime cimport ( | ||
npy_datetimestruct, dt64_to_dtstruct) | ||
from pandas._libs.tslibs.timezones cimport ( | ||
is_utc, is_tzlocal, get_dst_info) | ||
from pandas._libs.tslibs.timezones cimport get_tzconverter, TZConvertInfo | ||
from pandas._libs.tslibs.ccalendar cimport get_days_in_month | ||
from pandas._libs.tslibs.tzconversion cimport tz_convert_utc_to_tzlocal | ||
|
||
|
@@ -39,51 +38,42 @@ def get_resolution(const int64_t[:] stamps, tzinfo tz=None): | |
Py_ssize_t i, n = len(stamps) | ||
npy_datetimestruct dts | ||
int reso = RESO_DAY, curr_reso | ||
ndarray[int64_t] trans | ||
int64_t[:] deltas | ||
Py_ssize_t[:] pos | ||
int64_t local_val, delta | ||
|
||
if is_utc(tz) or tz is None: | ||
for i in range(n): | ||
if stamps[i] == NPY_NAT: | ||
continue | ||
dt64_to_dtstruct(stamps[i], &dts) | ||
curr_reso = _reso_stamp(&dts) | ||
if curr_reso < reso: | ||
reso = curr_reso | ||
elif is_tzlocal(tz): | ||
int64_t local_val | ||
TZConvertInfo info | ||
ndarray[intp_t, ndim=1] pos2 | ||
|
||
info = get_tzconverter(tz, stamps) | ||
|
||
if info.use_fixed: | ||
assert info.delta != NPY_NAT | ||
elif not info.use_utc and not info.use_tzlocal: | ||
assert info.utcoffsets is not NULL | ||
assert info.positions is not NULL | ||
pos2 = np.array(<intp_t[:n]>info.positions, dtype=np.intp) | ||
for i in range(n): | ||
if stamps[i] == NPY_NAT: | ||
continue | ||
v1 = info.positions[i] | ||
v2 = pos2[i] | ||
assert v1 == v2, (v1, v2) | ||
assert v1 < info.noffsets, (v1, info.noffsets, i, stamps[i]) | ||
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. cc @WillAyd I could use a fresh pair of eyes on this. This debugging assertion is failing on Linux and im at a loss as to why. The assertion on L265 of tzconversion should behave the same as this, but that one is passing. Any idea why things could change between there and here? |
||
assert pos2.max() < info.noffsets, (pos2.max(), info.noffsets) | ||
|
||
for i in range(n): | ||
if stamps[i] == NPY_NAT: | ||
continue | ||
|
||
if info.use_utc: | ||
local_val = stamps[i] | ||
elif info.use_tzlocal: | ||
local_val = tz_convert_utc_to_tzlocal(stamps[i], tz) | ||
dt64_to_dtstruct(local_val, &dts) | ||
curr_reso = _reso_stamp(&dts) | ||
if curr_reso < reso: | ||
reso = curr_reso | ||
else: | ||
# Adjust datetime64 timestamp, recompute datetimestruct | ||
trans, deltas, typ = get_dst_info(tz) | ||
|
||
if typ not in ['pytz', 'dateutil']: | ||
# static/fixed; in this case we know that len(delta) == 1 | ||
delta = deltas[0] | ||
for i in range(n): | ||
if stamps[i] == NPY_NAT: | ||
continue | ||
dt64_to_dtstruct(stamps[i] + delta, &dts) | ||
curr_reso = _reso_stamp(&dts) | ||
if curr_reso < reso: | ||
reso = curr_reso | ||
elif info.use_fixed: | ||
local_val = stamps[i] + info.delta | ||
else: | ||
pos = trans.searchsorted(stamps, side='right') - 1 | ||
for i in range(n): | ||
if stamps[i] == NPY_NAT: | ||
continue | ||
dt64_to_dtstruct(stamps[i] + deltas[pos[i]], &dts) | ||
curr_reso = _reso_stamp(&dts) | ||
if curr_reso < reso: | ||
reso = curr_reso | ||
local_val = stamps[i] + info.utcoffsets[info.positions[i]] | ||
|
||
dt64_to_dtstruct(local_val, &dts) | ||
curr_reso = _reso_stamp(&dts) | ||
if curr_reso < reso: | ||
reso = curr_reso | ||
|
||
return Resolution(reso) | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.