@@ -499,7 +499,7 @@ cdef inline void _localize_tso(_TSObject obj, object tz):
499
499
"""
500
500
cdef:
501
501
ndarray[int64_t] trans, deltas
502
- int64_t delta
502
+ int64_t delta, local_val
503
503
Py_ssize_t posn
504
504
datetime dt
505
505
@@ -510,11 +510,8 @@ cdef inline void _localize_tso(_TSObject obj, object tz):
510
510
elif obj.value == NPY_NAT:
511
511
pass
512
512
elif is_tzlocal(tz):
513
- dt64_to_dtstruct(obj.value, & obj.dts)
514
- dt = datetime(obj.dts.year, obj.dts.month, obj.dts.day, obj.dts.hour,
515
- obj.dts.min, obj.dts.sec, obj.dts.us, tz)
516
- delta = int (get_utcoffset(tz, dt).total_seconds()) * 1000000000
517
- dt64_to_dtstruct(obj.value + delta, & obj.dts)
513
+ local_val = tz_convert_utc_to_tzlocal(obj.value, tz)
514
+ dt64_to_dtstruct(local_val, & obj.dts)
518
515
else :
519
516
# Adjust datetime64 timestamp, recompute datetimestruct
520
517
trans, deltas, typ = get_dst_info(tz)
@@ -556,6 +553,66 @@ cdef inline datetime _localize_pydatetime(datetime dt, tzinfo tz):
556
553
# ----------------------------------------------------------------------
557
554
# Timezone Conversion
558
555
556
+ cdef inline int64_t tz_convert_tzlocal_to_utc(int64_t val, tzinfo tz):
557
+ """
558
+ Parameters
559
+ ----------
560
+ val : int64_t
561
+ tz : tzinfo
562
+
563
+ Returns
564
+ -------
565
+ utc_date : int64_t
566
+
567
+ See Also
568
+ --------
569
+ tz_convert_utc_to_tzlocal
570
+ """
571
+ cdef:
572
+ pandas_datetimestruct dts
573
+ int64_t utc_date, delta
574
+ datetime dt
575
+
576
+ dt64_to_dtstruct(val, & dts)
577
+ dt = datetime(dts.year, dts.month, dts.day, dts.hour,
578
+ dts.min, dts.sec, dts.us, tz)
579
+ delta = int (get_utcoffset(tz, dt).total_seconds()) * 1000000000
580
+ utc_date = val - delta
581
+ return utc_date
582
+
583
+
584
+ cdef inline int64_t tz_convert_utc_to_tzlocal(int64_t utc_val, tzinfo tz):
585
+ """
586
+ Parameters
587
+ ----------
588
+ utc_val : int64_t
589
+ tz : tzinfo
590
+
591
+ Returns
592
+ -------
593
+ local_val : int64_t
594
+
595
+ See Also
596
+ --------
597
+ tz_convert_tzlocal_to_utc
598
+
599
+ Notes
600
+ -----
601
+ The key difference between this and tz_convert_tzlocal_to_utc is a
602
+ an addition flipped to a subtraction in the last line.
603
+ """
604
+ cdef:
605
+ pandas_datetimestruct dts
606
+ int64_t local_val, delta
607
+ datetime dt
608
+
609
+ dt64_to_dtstruct(utc_val, & dts)
610
+ dt = datetime(dts.year, dts.month, dts.day, dts.hour,
611
+ dts.min, dts.sec, dts.us, tz)
612
+ delta = int (get_utcoffset(tz, dt).total_seconds()) * 1000000000
613
+ local_val = utc_val + delta
614
+ return local_val
615
+
559
616
560
617
cpdef int64_t tz_convert_single(int64_t val, object tz1, object tz2):
561
618
"""
@@ -590,11 +647,7 @@ cpdef int64_t tz_convert_single(int64_t val, object tz1, object tz2):
590
647
591
648
# Convert to UTC
592
649
if is_tzlocal(tz1):
593
- dt64_to_dtstruct(val, & dts)
594
- dt = datetime(dts.year, dts.month, dts.day, dts.hour,
595
- dts.min, dts.sec, dts.us, tz1)
596
- delta = int (get_utcoffset(tz1, dt).total_seconds()) * 1000000000
597
- utc_date = val - delta
650
+ utc_date = tz_convert_tzlocal_to_utc(val, tz1)
598
651
elif get_timezone(tz1) != ' UTC' :
599
652
trans, deltas, typ = get_dst_info(tz1)
600
653
pos = trans.searchsorted(val, side = ' right' ) - 1
@@ -608,11 +661,7 @@ cpdef int64_t tz_convert_single(int64_t val, object tz1, object tz2):
608
661
if get_timezone(tz2) == ' UTC' :
609
662
return utc_date
610
663
elif is_tzlocal(tz2):
611
- dt64_to_dtstruct(utc_date, & dts)
612
- dt = datetime(dts.year, dts.month, dts.day, dts.hour,
613
- dts.min, dts.sec, dts.us, tz2)
614
- delta = int (get_utcoffset(tz2, dt).total_seconds()) * 1000000000
615
- return utc_date + delta
664
+ return tz_convert_utc_to_tzlocal(utc_date, tz2)
616
665
617
666
# Convert UTC to other timezone
618
667
trans, deltas, typ = get_dst_info(tz2)
@@ -662,12 +711,7 @@ def tz_convert(ndarray[int64_t] vals, object tz1, object tz2):
662
711
if v == NPY_NAT:
663
712
utc_dates[i] = NPY_NAT
664
713
else :
665
- dt64_to_dtstruct(v, & dts)
666
- dt = datetime(dts.year, dts.month, dts.day, dts.hour,
667
- dts.min, dts.sec, dts.us, tz1)
668
- delta = (int (get_utcoffset(tz1, dt).total_seconds()) *
669
- 1000000000 )
670
- utc_dates[i] = v - delta
714
+ utc_dates[i] = tz_convert_tzlocal_to_utc(v, tz1)
671
715
else :
672
716
trans, deltas, typ = get_dst_info(tz1)
673
717
@@ -702,12 +746,7 @@ def tz_convert(ndarray[int64_t] vals, object tz1, object tz2):
702
746
if v == NPY_NAT:
703
747
result[i] = NPY_NAT
704
748
else :
705
- dt64_to_dtstruct(v, & dts)
706
- dt = datetime(dts.year, dts.month, dts.day, dts.hour,
707
- dts.min, dts.sec, dts.us, tz2)
708
- delta = (int (get_utcoffset(tz2, dt).total_seconds()) *
709
- 1000000000 )
710
- result[i] = v + delta
749
+ result[i] = tz_convert_utc_to_tzlocal(v, tz2)
711
750
return result
712
751
713
752
# Convert UTC to other timezone
@@ -777,11 +816,7 @@ def tz_localize_to_utc(ndarray[int64_t] vals, object tz, object ambiguous=None,
777
816
if is_tzlocal(tz):
778
817
for i in range (n):
779
818
v = vals[i]
780
- dt64_to_dtstruct(v, & dts)
781
- dt = datetime(dts.year, dts.month, dts.day, dts.hour,
782
- dts.min, dts.sec, dts.us, tz)
783
- delta = int (get_utcoffset(tz, dt).total_seconds()) * 1000000000
784
- result[i] = v - delta
819
+ result[i] = tz_convert_tzlocal_to_utc(v, tz)
785
820
return result
786
821
787
822
if is_string_object(ambiguous):
@@ -1024,11 +1059,8 @@ cdef ndarray[int64_t] _normalize_local(ndarray[int64_t] stamps, object tz):
1024
1059
if stamps[i] == NPY_NAT:
1025
1060
result[i] = NPY_NAT
1026
1061
continue
1027
- dt64_to_dtstruct(stamps[i], & dts)
1028
- dt = datetime(dts.year, dts.month, dts.day, dts.hour,
1029
- dts.min, dts.sec, dts.us, tz)
1030
- delta = int (get_utcoffset(tz, dt).total_seconds()) * 1000000000
1031
- dt64_to_dtstruct(stamps[i] + delta, & dts)
1062
+ local_val = tz_convert_utc_to_tzlocal(stamps[i], tz)
1063
+ dt64_to_dtstruct(local_val, & dts)
1032
1064
result[i] = _normalized_stamp(& dts)
1033
1065
else :
1034
1066
# Adjust datetime64 timestamp, recompute datetimestruct
@@ -1097,7 +1129,7 @@ def is_date_array_normalized(ndarray[int64_t] stamps, tz=None):
1097
1129
Py_ssize_t i, n = len (stamps)
1098
1130
ndarray[int64_t] trans, deltas
1099
1131
pandas_datetimestruct dts
1100
- datetime dt
1132
+ int64_t local_val
1101
1133
1102
1134
if tz is None or is_utc(tz):
1103
1135
for i in range (n):
@@ -1106,11 +1138,9 @@ def is_date_array_normalized(ndarray[int64_t] stamps, tz=None):
1106
1138
return False
1107
1139
elif is_tzlocal(tz):
1108
1140
for i in range (n):
1109
- dt64_to_dtstruct(stamps[i], & dts)
1110
- dt = datetime(dts.year, dts.month, dts.day, dts.hour, dts.min,
1111
- dts.sec, dts.us, tz)
1112
- dt = dt + tz.utcoffset(dt)
1113
- if (dt.hour + dt.minute + dt.second + dt.microsecond) > 0 :
1141
+ local_val = tz_convert_utc_to_tzlocal(stamps[i], tz)
1142
+ dt64_to_dtstruct(local_val, & dts)
1143
+ if (dts.hour + dts.min + dts.sec + dts.us) > 0 :
1114
1144
return False
1115
1145
else :
1116
1146
trans, deltas, typ = get_dst_info(tz)
0 commit comments