@@ -45,7 +45,7 @@ static int monthToQuarter(int month) { return ((month - 1) / 3) + 1; }
4545/* Find the absdate (days elapsed since datetime(1, 1, 1)
4646 * for the given year/month/day.
4747 * Assumes GREGORIAN_CALENDAR */
48- static npy_int64 dInfoCalc_SetFromDateAndTime (int year , int month , int day ) {
48+ npy_int64 absdate_from_ymd (int year , int month , int day ) {
4949 /* Calculate the absolute date */
5050 pandas_datetimestruct dts ;
5151 npy_int64 unix_date ;
@@ -68,8 +68,6 @@ static int dInfoCalc_SetFromAbsDate(register struct date_info *dinfo,
6868 dinfo -> year = dts .year ;
6969 dinfo -> month = dts .month ;
7070 dinfo -> day = dts .day ;
71-
72- dinfo -> absdate = absdate ;
7371 return 0 ;
7472}
7573
@@ -100,8 +98,7 @@ PANDAS_INLINE int get_freq_group(int freq) { return (freq / 1000) * 1000; }
10098PANDAS_INLINE int get_freq_group_index (int freq ) { return freq / 1000 ; }
10199
102100
103- PANDAS_INLINE npy_int64 get_daytime_conversion_factor (int from_index ,
104- int to_index ) {
101+ npy_int64 get_daytime_conversion_factor (int from_index , int to_index ) {
105102 int row = min_value (from_index , to_index );
106103 int col = max_value (from_index , to_index );
107104 // row or col < 6 means frequency strictly lower than Daily, which
@@ -144,9 +141,9 @@ static npy_int64 DtoB_weekday(npy_int64 absdate) {
144141 return (((absdate ) / 7 ) * 5 ) + (absdate ) % 7 - BDAY_OFFSET ;
145142}
146143
147- static npy_int64 DtoB (struct date_info * dinfo , int roll_back ) {
144+ static npy_int64 DtoB (struct date_info * dinfo ,
145+ int roll_back , npy_int64 absdate ) {
148146 int day_of_week = dayofweek (dinfo -> year , dinfo -> month , dinfo -> day );
149- npy_int64 absdate = dinfo -> absdate ;
150147
151148 if (roll_back == 1 ) {
152149 if (day_of_week > 4 ) {
@@ -162,9 +159,6 @@ static npy_int64 DtoB(struct date_info *dinfo, int roll_back) {
162159 return DtoB_weekday (absdate );
163160}
164161
165- static npy_int64 absdate_from_ymd (int y , int m , int d ) {
166- return dInfoCalc_SetFromDateAndTime (y , m , d );
167- }
168162
169163//************ FROM DAILY ***************
170164
@@ -224,15 +218,16 @@ static npy_int64 asfreq_DTtoW(npy_int64 ordinal, asfreq_info *af_info) {
224218
225219static npy_int64 asfreq_DTtoB (npy_int64 ordinal , asfreq_info * af_info ) {
226220 struct date_info dinfo ;
221+ npy_int64 absdate ;
227222 int roll_back ;
228223
229224 ordinal = downsample_daytime (ordinal , af_info );
230-
231- dInfoCalc_SetFromAbsDate (& dinfo , ordinal + ORD_OFFSET );
225+ absdate = ordinal + ORD_OFFSET ;
226+ dInfoCalc_SetFromAbsDate (& dinfo , absdate );
232227
233228 // This usage defines roll_back the opposite way from the others
234229 roll_back = 1 - af_info -> is_end ;
235- return DtoB (& dinfo , roll_back );
230+ return DtoB (& dinfo , roll_back , absdate );
236231}
237232
238233// all intra day calculations are now done within one function
@@ -298,11 +293,11 @@ static npy_int64 asfreq_WtoW(npy_int64 ordinal, asfreq_info *af_info) {
298293
299294static npy_int64 asfreq_WtoB (npy_int64 ordinal , asfreq_info * af_info ) {
300295 struct date_info dinfo ;
296+ npy_int64 absdate = asfreq_WtoDT (ordinal , af_info ) + ORD_OFFSET ;
301297 int roll_back = af_info -> is_end ;
302- dInfoCalc_SetFromAbsDate (
303- & dinfo , asfreq_WtoDT (ordinal , af_info ) + ORD_OFFSET );
298+ dInfoCalc_SetFromAbsDate (& dinfo , absdate );
304299
305- return DtoB (& dinfo , roll_back );
300+ return DtoB (& dinfo , roll_back , absdate );
306301}
307302
308303//************ FROM MONTHLY ***************
@@ -338,12 +333,12 @@ static npy_int64 asfreq_MtoW(npy_int64 ordinal, asfreq_info *af_info) {
338333
339334static npy_int64 asfreq_MtoB (npy_int64 ordinal , asfreq_info * af_info ) {
340335 struct date_info dinfo ;
336+ npy_int64 absdate = asfreq_MtoDT (ordinal , af_info ) + ORD_OFFSET ;
341337 int roll_back = af_info -> is_end ;
342338
343- dInfoCalc_SetFromAbsDate (
344- & dinfo , asfreq_MtoDT (ordinal , af_info ) + ORD_OFFSET );
339+ dInfoCalc_SetFromAbsDate (& dinfo , absdate );
345340
346- return DtoB (& dinfo , roll_back );
341+ return DtoB (& dinfo , roll_back , absdate );
347342}
348343
349344//************ FROM QUARTERLY ***************
@@ -393,12 +388,12 @@ static npy_int64 asfreq_QtoW(npy_int64 ordinal, asfreq_info *af_info) {
393388
394389static npy_int64 asfreq_QtoB (npy_int64 ordinal , asfreq_info * af_info ) {
395390 struct date_info dinfo ;
391+ npy_int64 absdate = asfreq_QtoDT (ordinal , af_info ) + ORD_OFFSET ;
396392 int roll_back = af_info -> is_end ;
397393
398- dInfoCalc_SetFromAbsDate (
399- & dinfo , asfreq_QtoDT (ordinal , af_info ) + ORD_OFFSET );
394+ dInfoCalc_SetFromAbsDate (& dinfo , absdate );
400395
401- return DtoB (& dinfo , roll_back );
396+ return DtoB (& dinfo , roll_back , absdate );
402397}
403398
404399//************ FROM ANNUAL ***************
@@ -439,11 +434,11 @@ static npy_int64 asfreq_AtoW(npy_int64 ordinal, asfreq_info *af_info) {
439434
440435static npy_int64 asfreq_AtoB (npy_int64 ordinal , asfreq_info * af_info ) {
441436 struct date_info dinfo ;
437+ npy_int64 absdate = asfreq_AtoDT (ordinal , af_info ) + ORD_OFFSET ;
442438 int roll_back = af_info -> is_end ;
443- dInfoCalc_SetFromAbsDate (
444- & dinfo , asfreq_AtoDT (ordinal , af_info ) + ORD_OFFSET );
439+ dInfoCalc_SetFromAbsDate (& dinfo , absdate );
445440
446- return DtoB (& dinfo , roll_back );
441+ return DtoB (& dinfo , roll_back , absdate );
447442}
448443
449444static npy_int64 nofunc (npy_int64 ordinal , asfreq_info * af_info ) {
@@ -675,65 +670,6 @@ freq_conv_func get_asfreq_func(int fromFreq, int toFreq) {
675670 }
676671}
677672
678- double get_abs_time (int freq , npy_int64 date_ordinal , npy_int64 ordinal ) {
679- int freq_index , day_index , base_index ;
680- npy_int64 per_day , start_ord ;
681- double unit , result ;
682-
683- if (freq <= FR_DAY ) {
684- return 0 ;
685- }
686-
687- freq_index = get_freq_group_index (freq );
688- day_index = get_freq_group_index (FR_DAY );
689- base_index = get_freq_group_index (FR_SEC );
690-
691- per_day = get_daytime_conversion_factor (day_index , freq_index );
692- unit = get_daytime_conversion_factor (freq_index , base_index );
693-
694- if (base_index < freq_index ) {
695- unit = 1 / unit ;
696- }
697-
698- start_ord = date_ordinal * per_day ;
699- result = (double )(unit * (ordinal - start_ord ));
700- return result ;
701- }
702-
703- /* Sets the time part of the DateTime object. */
704- static int dInfoCalc_SetFromAbsTime (struct date_info * dinfo , double abstime ) {
705- int inttime ;
706- int hour , minute ;
707- double second ;
708-
709- inttime = (int )abstime ;
710- hour = inttime / 3600 ;
711- minute = (inttime % 3600 ) / 60 ;
712- second = abstime - (double )(hour * 3600 + minute * 60 );
713-
714- dinfo -> hour = hour ;
715- dinfo -> minute = minute ;
716- dinfo -> second = second ;
717- return 0 ;
718- }
719-
720- /* Set the instance's value using the given date and time.
721- Assumes GREGORIAN_CALENDAR. */
722- static int dInfoCalc_SetFromAbsDateTime (struct date_info * dinfo ,
723- npy_int64 absdate , double abstime ) {
724- /* Bounds check */
725- // The calling function is responsible for ensuring that
726- // abstime >= 0.0 && abstime <= 86400
727-
728- /* Calculate the date */
729- dInfoCalc_SetFromAbsDate (dinfo , absdate );
730-
731- /* Calculate the time */
732- dInfoCalc_SetFromAbsTime (dinfo , abstime );
733-
734- return 0 ;
735- }
736-
737673/* ------------------------------------------------------------------
738674 * New pandas API-helper code, to expose to cython
739675 * ------------------------------------------------------------------*/
@@ -750,185 +686,3 @@ npy_int64 asfreq(npy_int64 period_ordinal, int freq1, int freq2,
750686 val = (* func )(period_ordinal , & finfo );
751687 return val ;
752688}
753-
754- /* generate an ordinal in period space */
755- npy_int64 get_period_ordinal (int year , int month , int day , int hour , int minute ,
756- int second , int microseconds , int picoseconds ,
757- int freq ) {
758- npy_int64 absdays , delta , seconds ;
759- npy_int64 weeks , days ;
760- npy_int64 ordinal , day_adj ;
761- int freq_group , fmonth , mdiff ;
762- freq_group = get_freq_group (freq );
763-
764- if (freq == FR_SEC || freq == FR_MS || freq == FR_US || freq == FR_NS ) {
765- absdays = absdate_from_ymd (year , month , day );
766- delta = (absdays - ORD_OFFSET );
767- seconds =
768- (npy_int64 )(delta * 86400 + hour * 3600 + minute * 60 + second );
769-
770- switch (freq ) {
771- case FR_MS :
772- return seconds * 1000 + microseconds / 1000 ;
773-
774- case FR_US :
775- return seconds * 1000000 + microseconds ;
776-
777- case FR_NS :
778- return seconds * 1000000000 + microseconds * 1000 +
779- picoseconds / 1000 ;
780- }
781-
782- return seconds ;
783- }
784-
785- if (freq == FR_MIN ) {
786- absdays = absdate_from_ymd (year , month , day );
787- delta = (absdays - ORD_OFFSET );
788- return (npy_int64 )(delta * 1440 + hour * 60 + minute );
789- }
790-
791- if (freq == FR_HR ) {
792- absdays = absdate_from_ymd (year , month , day );
793- delta = (absdays - ORD_OFFSET );
794- return (npy_int64 )(delta * 24 + hour );
795- }
796-
797- if (freq == FR_DAY ) {
798- return (npy_int64 )(absdate_from_ymd (year , month , day ) - ORD_OFFSET );
799- }
800-
801- if (freq == FR_UND ) {
802- return (npy_int64 )(absdate_from_ymd (year , month , day ) - ORD_OFFSET );
803- }
804-
805- if (freq == FR_BUS ) {
806- days = absdate_from_ymd (year , month , day );
807- // calculate the current week assuming sunday as last day of a week
808- weeks = (days - BASE_WEEK_TO_DAY_OFFSET ) / DAYS_PER_WEEK ;
809- // calculate the current weekday (in range 1 .. 7)
810- delta = (days - BASE_WEEK_TO_DAY_OFFSET ) % DAYS_PER_WEEK + 1 ;
811- // return the number of business days in full weeks plus the business
812- // days in the last - possible partial - week
813- return (npy_int64 )(weeks * BUSINESS_DAYS_PER_WEEK ) +
814- (delta <= BUSINESS_DAYS_PER_WEEK ? delta
815- : BUSINESS_DAYS_PER_WEEK + 1 ) -
816- BDAY_OFFSET ;
817- }
818-
819- if (freq_group == FR_WK ) {
820- ordinal = (npy_int64 )absdate_from_ymd (year , month , day );
821- day_adj = freq - FR_WK ;
822- return (ordinal - (1 + day_adj )) / 7 + 1 - WEEK_OFFSET ;
823- }
824-
825- if (freq == FR_MTH ) {
826- return (year - BASE_YEAR ) * 12 + month - 1 ;
827- }
828-
829- if (freq_group == FR_QTR ) {
830- fmonth = freq - FR_QTR ;
831- if (fmonth == 0 ) fmonth = 12 ;
832-
833- mdiff = month - fmonth ;
834- if (mdiff < 0 ) mdiff += 12 ;
835- if (month >= fmonth ) mdiff += 12 ;
836-
837- return (year - BASE_YEAR ) * 4 + (mdiff - 1 ) / 3 ;
838- }
839-
840- if (freq_group == FR_ANN ) {
841- fmonth = freq - FR_ANN ;
842- if (fmonth == 0 ) fmonth = 12 ;
843- if (month <= fmonth ) {
844- return year - BASE_YEAR ;
845- } else {
846- return year - BASE_YEAR + 1 ;
847- }
848- }
849-
850- Py_Error (PyExc_RuntimeError , "Unable to generate frequency ordinal" );
851-
852- onError :
853- return INT_ERR_CODE ;
854- }
855-
856- /*
857- Returns the proleptic Gregorian ordinal of the date, as an integer.
858- This corresponds to the number of days since Jan., 1st, 1AD.
859- When the instance has a frequency less than daily, the proleptic date
860- is calculated for the last day of the period.
861- */
862-
863- npy_int64 get_python_ordinal (npy_int64 period_ordinal , int freq ) {
864- asfreq_info af_info ;
865- freq_conv_func toDaily = NULL ;
866-
867- if (freq == FR_DAY ) return period_ordinal + ORD_OFFSET ;
868-
869- toDaily = get_asfreq_func (freq , FR_DAY );
870- get_asfreq_info (freq , FR_DAY , 'E' , & af_info );
871-
872- return toDaily (period_ordinal , & af_info ) + ORD_OFFSET ;
873- }
874-
875-
876- int get_yq (npy_int64 ordinal , int freq , int * quarter , int * year ) {
877- asfreq_info af_info ;
878- int qtr_freq ;
879- npy_int64 daily_ord ;
880- freq_conv_func toDaily = NULL ;
881-
882- toDaily = get_asfreq_func (freq , FR_DAY );
883- get_asfreq_info (freq , FR_DAY , 'E' , & af_info );
884-
885- daily_ord = toDaily (ordinal , & af_info );
886-
887- if (get_freq_group (freq ) == FR_QTR ) {
888- qtr_freq = freq ;
889- } else {
890- qtr_freq = FR_QTR ;
891- }
892- get_asfreq_info (FR_DAY , qtr_freq , 'E' , & af_info );
893-
894- DtoQ_yq (daily_ord , & af_info , year , quarter );
895- return 0 ;
896- }
897-
898- int _quarter_year (npy_int64 ordinal , int freq , int * year , int * quarter ) {
899- asfreq_info af_info ;
900- int qtr_freq ;
901-
902- ordinal = get_python_ordinal (ordinal , freq ) - ORD_OFFSET ;
903-
904- if (get_freq_group (freq ) == FR_QTR )
905- qtr_freq = freq ;
906- else
907- qtr_freq = FR_QTR ;
908-
909- get_asfreq_info (FR_DAY , qtr_freq , 'E' , & af_info );
910-
911- DtoQ_yq (ordinal , & af_info , year , quarter );
912-
913- if ((qtr_freq % 1000 ) > 12 ) * year -= 1 ;
914-
915- return 0 ;
916- }
917-
918-
919- int get_date_info (npy_int64 ordinal , int freq , struct date_info * dinfo ) {
920- npy_int64 absdate = get_python_ordinal (ordinal , freq );
921- double abstime = get_abs_time (freq , absdate - ORD_OFFSET , ordinal );
922-
923- while (abstime < 0 ) {
924- abstime += 86400 ;
925- absdate -= 1 ;
926- }
927- while (abstime >= 86400 ) {
928- abstime -= 86400 ;
929- absdate += 1 ;
930- }
931-
932- dInfoCalc_SetFromAbsDateTime (dinfo , absdate , abstime );
933- return 0 ;
934- }
0 commit comments