Skip to content

Commit 591da6b

Browse files
authored
REF: make tz_convert match pattern eslewhere (#35255)
1 parent 859eb6a commit 591da6b

File tree

1 file changed

+45
-70
lines changed

1 file changed

+45
-70
lines changed

pandas/_libs/tslibs/tzconversion.pyx

+45-70
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,10 @@ cpdef int64_t tz_convert_from_utc_single(int64_t val, tzinfo tz):
382382
converted: int64
383383
"""
384384
cdef:
385-
int64_t arr[1]
385+
int64_t delta
386+
int64_t[:] deltas
387+
ndarray[int64_t, ndim=1] trans
388+
intp_t pos
386389

387390
if val == NPY_NAT:
388391
return val
@@ -391,9 +394,14 @@ cpdef int64_t tz_convert_from_utc_single(int64_t val, tzinfo tz):
391394
return val
392395
elif is_tzlocal(tz):
393396
return _tz_convert_tzlocal_utc(val, tz, to_utc=False)
397+
elif is_fixed_offset(tz):
398+
_, deltas, _ = get_dst_info(tz)
399+
delta = deltas[0]
400+
return val + delta
394401
else:
395-
arr[0] = val
396-
return _tz_convert_dst(arr, tz)[0]
402+
trans, deltas, _ = get_dst_info(tz)
403+
pos = trans.searchsorted(val, side="right") - 1
404+
return val + deltas[pos]
397405

398406

399407
def tz_convert_from_utc(int64_t[:] vals, tzinfo tz):
@@ -435,9 +443,12 @@ cdef int64_t[:] _tz_convert_from_utc(int64_t[:] vals, tzinfo tz):
435443
converted : ndarray[int64_t]
436444
"""
437445
cdef:
438-
int64_t[:] converted
446+
int64_t[:] converted, deltas
439447
Py_ssize_t i, n = len(vals)
440-
int64_t val
448+
int64_t val, delta
449+
intp_t[:] pos
450+
ndarray[int64_t] trans
451+
str typ
441452

442453
if is_utc(tz):
443454
converted = vals
@@ -450,7 +461,35 @@ cdef int64_t[:] _tz_convert_from_utc(int64_t[:] vals, tzinfo tz):
450461
else:
451462
converted[i] = _tz_convert_tzlocal_utc(val, tz, to_utc=False)
452463
else:
453-
converted = _tz_convert_dst(vals, tz)
464+
converted = np.empty(n, dtype=np.int64)
465+
466+
trans, deltas, typ = get_dst_info(tz)
467+
468+
if typ not in ["pytz", "dateutil"]:
469+
# FixedOffset, we know len(deltas) == 1
470+
delta = deltas[0]
471+
472+
for i in range(n):
473+
val = vals[i]
474+
if val == NPY_NAT:
475+
converted[i] = val
476+
else:
477+
converted[i] = val + delta
478+
479+
else:
480+
pos = trans.searchsorted(vals, side="right") - 1
481+
482+
for i in range(n):
483+
val = vals[i]
484+
if val == NPY_NAT:
485+
converted[i] = val
486+
else:
487+
if pos[i] < 0:
488+
# TODO: How is this reached? Should we be checking for
489+
# it elsewhere?
490+
raise ValueError("First time before start of DST info")
491+
492+
converted[i] = val + deltas[pos[i]]
454493

455494
return converted
456495

@@ -537,67 +576,3 @@ cdef int64_t _tz_convert_tzlocal_utc(int64_t val, tzinfo tz, bint to_utc=True,
537576
return val - delta
538577
else:
539578
return val + delta
540-
541-
542-
@cython.boundscheck(False)
543-
@cython.wraparound(False)
544-
cdef int64_t[:] _tz_convert_dst(const int64_t[:] values, tzinfo tz):
545-
"""
546-
tz_convert for non-UTC non-tzlocal cases where we have to check
547-
DST transitions pointwise.
548-
549-
Parameters
550-
----------
551-
values : ndarray[int64_t]
552-
tz : tzinfo
553-
554-
Returns
555-
-------
556-
result : ndarray[int64_t]
557-
"""
558-
cdef:
559-
Py_ssize_t n = len(values)
560-
Py_ssize_t i
561-
intp_t[:] pos
562-
int64_t[:] result = np.empty(n, dtype=np.int64)
563-
ndarray[int64_t] trans
564-
int64_t[:] deltas
565-
int64_t v, delta
566-
str typ
567-
568-
# tz is assumed _not_ to be tzlocal; that should go
569-
# through _tz_convert_tzlocal_utc
570-
571-
trans, deltas, typ = get_dst_info(tz)
572-
573-
if typ not in ["pytz", "dateutil"]:
574-
# FixedOffset, we know len(deltas) == 1
575-
delta = deltas[0]
576-
577-
for i in range(n):
578-
v = values[i]
579-
if v == NPY_NAT:
580-
result[i] = v
581-
else:
582-
result[i] = v + delta
583-
584-
else:
585-
# Previously, this search was done pointwise to try and benefit
586-
# from getting to skip searches for iNaTs. However, it seems call
587-
# overhead dominates the search time so doing it once in bulk
588-
# is substantially faster (GH#24603)
589-
pos = trans.searchsorted(values, side="right") - 1
590-
591-
for i in range(n):
592-
v = values[i]
593-
if v == NPY_NAT:
594-
result[i] = v
595-
else:
596-
if pos[i] < 0:
597-
# TODO: How is this reached? Should we be checking for
598-
# it elsewhere?
599-
raise ValueError("First time before start of DST info")
600-
601-
result[i] = v + deltas[pos[i]]
602-
603-
return result

0 commit comments

Comments
 (0)