@@ -642,9 +642,7 @@ cdef int64_t _tz_localize_using_tzinfo_api(
642
642
if not to_utc:
643
643
# tz.utcoffset only makes sense if datetime
644
644
# is _wall time_, so if val is a UTC timestamp convert to wall time
645
- dt = datetime_new(dts.year, dts.month, dts.day, dts.hour,
646
- dts.min, dts.sec, dts.us, utc_pytz)
647
- dt = dt.astimezone(tz)
645
+ dt = _astimezone(dts, tz)
648
646
649
647
if fold is not NULL :
650
648
# NB: fold is only passed with to_utc=False
@@ -658,6 +656,27 @@ cdef int64_t _tz_localize_using_tzinfo_api(
658
656
return delta
659
657
660
658
659
+ cdef datetime _astimezone(npy_datetimestruct dts, tzinfo tz):
660
+ """
661
+ Optimized equivalent to:
662
+
663
+ dt = datetime(dts.year, dts.month, dts.day, dts.hour,
664
+ dts.min, dts.sec, dts.us, utc_pytz)
665
+ dt = dt.astimezone(tz)
666
+
667
+ Derived from the datetime.astimezone implementation at
668
+ https://github.com/python/cpython/blob/main/Modules/_datetimemodule.c#L6187
669
+
670
+ NB: we are assuming tz is not None.
671
+ """
672
+ cdef:
673
+ datetime result
674
+
675
+ result = datetime_new(dts.year, dts.month, dts.day, dts.hour,
676
+ dts.min, dts.sec, dts.us, tz)
677
+ return tz.fromutc(result)
678
+
679
+
661
680
# NB: relies on dateutil internals, subject to change.
662
681
@ cython.boundscheck (False )
663
682
@ cython.wraparound (False )
0 commit comments