@@ -15,7 +15,7 @@ from pandas._libs.tslibs.ccalendar import (
15
15
get_locale_names, MONTHS_FULL, DAYS_FULL, DAY_SECONDS)
16
16
from pandas._libs.tslibs.ccalendar cimport (
17
17
get_days_in_month, is_leapyear, dayofweek, get_week_of_year,
18
- get_day_of_year)
18
+ get_day_of_year, get_iso_calendar )
19
19
from pandas._libs.tslibs.np_datetime cimport (
20
20
npy_datetimestruct, pandas_timedeltastruct, dt64_to_dtstruct,
21
21
td64_to_tdstruct)
@@ -670,3 +670,42 @@ cpdef isleapyear_arr(ndarray years):
670
670
np.logical_and(years % 4 == 0 ,
671
671
years % 100 > 0 ))] = 1
672
672
return out.view(bool )
673
+
674
+
675
+ @ cython.wraparound (False )
676
+ @ cython.boundscheck (False )
677
+ def build_isocalendar_sarray (const int64_t[:] dtindex ):
678
+ """
679
+ Given a int64-based datetime array, return the ISO 8601 year, week, and day
680
+ as a structured array.
681
+ """
682
+ cdef:
683
+ Py_ssize_t i, count = len (dtindex)
684
+ npy_datetimestruct dts
685
+ ndarray[int32_t] iso_years, iso_weeks, days
686
+ (int32_t, int32_t, int32_t) ret_val
687
+
688
+ sa_dtype = [
689
+ (" year" , " i4" ),
690
+ (" week" , " i4" ),
691
+ (" day" , " i4" ),
692
+ ]
693
+
694
+ out = np.empty(count, dtype = sa_dtype)
695
+
696
+ iso_years = out[" year" ]
697
+ iso_weeks = out[" week" ]
698
+ days = out[" day" ]
699
+
700
+ with nogil:
701
+ for i in range (count):
702
+ if dtindex[i] == NPY_NAT:
703
+ ret_val = - 1 , - 1 , - 1
704
+ else :
705
+ dt64_to_dtstruct(dtindex[i], & dts)
706
+ ret_val = get_iso_calendar(dts.year, dts.month, dts.day)
707
+
708
+ iso_years[i] = ret_val[0 ]
709
+ iso_weeks[i] = ret_val[1 ]
710
+ days[i] = ret_val[2 ]
711
+ return out
0 commit comments