@@ -41,6 +41,7 @@ from pandas._libs.tslibs.np_datetime cimport (
41
41
npy_datetimestruct,
42
42
npy_datetimestruct_to_datetime,
43
43
pandas_datetime_to_datetimestruct,
44
+ pydatetime_to_dt64,
44
45
pydatetime_to_dtstruct,
45
46
string_to_dts,
46
47
)
@@ -65,6 +66,7 @@ from pandas._libs.tslibs.nattype cimport (
65
66
c_NaT as NaT,
66
67
c_nat_strings as nat_strings,
67
68
)
69
+ from pandas._libs.tslibs.timestamps cimport _Timestamp
68
70
from pandas._libs.tslibs.tzconversion cimport (
69
71
Localizer,
70
72
tz_localize_to_utc_single,
@@ -208,9 +210,10 @@ cdef class _TSObject:
208
210
self .fold = 0
209
211
self .creso = NPY_FR_ns # default value
210
212
211
- cdef void ensure_reso(self , NPY_DATETIMEUNIT creso):
213
+ cdef int64_t ensure_reso(self , NPY_DATETIMEUNIT creso) except ? - 1 :
212
214
if self .creso != creso:
213
215
self .value = convert_reso(self .value, self .creso, creso, False )
216
+ return self .value
214
217
215
218
216
219
cdef _TSObject convert_to_tsobject(object ts, tzinfo tz, str unit,
@@ -642,3 +645,99 @@ cpdef inline datetime localize_pydatetime(datetime dt, tzinfo tz):
642
645
elif isinstance (dt, ABCTimestamp):
643
646
return dt.tz_localize(tz)
644
647
return _localize_pydatetime(dt, tz)
648
+
649
+
650
+ cdef tzinfo convert_timezone(
651
+ tzinfo tz_in,
652
+ tzinfo tz_out,
653
+ bint found_naive,
654
+ bint found_tz,
655
+ bint utc_convert,
656
+ ):
657
+ """
658
+ Validate that ``tz_in`` can be converted/localized to ``tz_out``.
659
+
660
+ Parameters
661
+ ----------
662
+ tz_in : tzinfo
663
+ Timezone info of element being processed.
664
+ tz_out : tzinfo
665
+ Timezone info of output.
666
+ found_naive : bool
667
+ Whether a timezone-naive element has been found so far.
668
+ found_tz : bool
669
+ Whether a timezone-aware element has been found so far.
670
+ utc_convert : bool
671
+ Whether to convert/localize to UTC.
672
+
673
+ Returns
674
+ -------
675
+ tz_info
676
+ Timezone info of output.
677
+
678
+ Raises
679
+ ------
680
+ ValueError
681
+ If ``tz_in`` can't be converted/localized to ``tz_out``.
682
+ """
683
+ if tz_in is not None :
684
+ if utc_convert:
685
+ pass
686
+ elif found_naive:
687
+ raise ValueError (' Tz-aware datetime.datetime '
688
+ ' cannot be converted to '
689
+ ' datetime64 unless utc=True' )
690
+ elif tz_out is not None and not tz_compare(tz_out, tz_in):
691
+ raise ValueError (' Tz-aware datetime.datetime '
692
+ ' cannot be converted to '
693
+ ' datetime64 unless utc=True' )
694
+ else :
695
+ tz_out = tz_in
696
+ else :
697
+ if found_tz and not utc_convert:
698
+ raise ValueError (' Cannot mix tz-aware with '
699
+ ' tz-naive values' )
700
+ return tz_out
701
+
702
+
703
+ cdef int64_t parse_pydatetime(
704
+ object val,
705
+ npy_datetimestruct * dts,
706
+ bint utc_convert,
707
+ ) except ? - 1 :
708
+ """
709
+ Convert pydatetime to datetime64.
710
+
711
+ Parameters
712
+ ----------
713
+ val
714
+ Element being processed.
715
+ dts : *npy_datetimestruct
716
+ Needed to use in pydatetime_to_dt64, which writes to it.
717
+ utc_convert : bool
718
+ Whether to convert/localize to UTC.
719
+
720
+ Raises
721
+ ------
722
+ OutOfBoundsDatetime
723
+ """
724
+ cdef:
725
+ _TSObject _ts
726
+ int64_t result
727
+
728
+ if val.tzinfo is not None :
729
+ if utc_convert:
730
+ _ts = convert_datetime_to_tsobject(val, None )
731
+ _ts.ensure_reso(NPY_FR_ns)
732
+ result = _ts.value
733
+ else :
734
+ _ts = convert_datetime_to_tsobject(val, None )
735
+ _ts.ensure_reso(NPY_FR_ns)
736
+ result = _ts.value
737
+ else :
738
+ if isinstance (val, _Timestamp):
739
+ result = val.as_unit(" ns" ).value
740
+ else :
741
+ result = pydatetime_to_dt64(val, dts)
742
+ check_dts_bounds(dts)
743
+ return result
0 commit comments