diff --git a/pandas/_libs/tslibs/conversion.pyx b/pandas/_libs/tslibs/conversion.pyx index 8cfaa1f7b5cea..f825a4c8ed2c1 100644 --- a/pandas/_libs/tslibs/conversion.pyx +++ b/pandas/_libs/tslibs/conversion.pyx @@ -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 @@ -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): """ 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): @@ -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): @@ -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 @@ -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) @@ -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) @@ -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 @@ -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 @@ -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): @@ -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: @@ -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 @@ -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] dt64_to_dtstruct(stamps[i] + deltas[pos], &dts) if (dts.hour + dts.min + dts.sec + dts.us) > 0: