@@ -45,7 +45,7 @@ static int monthToQuarter(int month) { return ((month - 1) / 3) + 1; }
45
45
/* Find the absdate (days elapsed since datetime(1, 1, 1)
46
46
* for the given year/month/day.
47
47
* 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 ) {
49
49
/* Calculate the absolute date */
50
50
pandas_datetimestruct dts ;
51
51
npy_int64 unix_date ;
@@ -68,8 +68,6 @@ static int dInfoCalc_SetFromAbsDate(register struct date_info *dinfo,
68
68
dinfo -> year = dts .year ;
69
69
dinfo -> month = dts .month ;
70
70
dinfo -> day = dts .day ;
71
-
72
- dinfo -> absdate = absdate ;
73
71
return 0 ;
74
72
}
75
73
@@ -100,8 +98,7 @@ PANDAS_INLINE int get_freq_group(int freq) { return (freq / 1000) * 1000; }
100
98
PANDAS_INLINE int get_freq_group_index (int freq ) { return freq / 1000 ; }
101
99
102
100
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 ) {
105
102
int row = min_value (from_index , to_index );
106
103
int col = max_value (from_index , to_index );
107
104
// row or col < 6 means frequency strictly lower than Daily, which
@@ -144,9 +141,9 @@ static npy_int64 DtoB_weekday(npy_int64 absdate) {
144
141
return (((absdate ) / 7 ) * 5 ) + (absdate ) % 7 - BDAY_OFFSET ;
145
142
}
146
143
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 ) {
148
146
int day_of_week = dayofweek (dinfo -> year , dinfo -> month , dinfo -> day );
149
- npy_int64 absdate = dinfo -> absdate ;
150
147
151
148
if (roll_back == 1 ) {
152
149
if (day_of_week > 4 ) {
@@ -162,9 +159,6 @@ static npy_int64 DtoB(struct date_info *dinfo, int roll_back) {
162
159
return DtoB_weekday (absdate );
163
160
}
164
161
165
- static npy_int64 absdate_from_ymd (int y , int m , int d ) {
166
- return dInfoCalc_SetFromDateAndTime (y , m , d );
167
- }
168
162
169
163
//************ FROM DAILY ***************
170
164
@@ -224,15 +218,16 @@ static npy_int64 asfreq_DTtoW(npy_int64 ordinal, asfreq_info *af_info) {
224
218
225
219
static npy_int64 asfreq_DTtoB (npy_int64 ordinal , asfreq_info * af_info ) {
226
220
struct date_info dinfo ;
221
+ npy_int64 absdate ;
227
222
int roll_back ;
228
223
229
224
ordinal = downsample_daytime (ordinal , af_info );
230
-
231
- dInfoCalc_SetFromAbsDate (& dinfo , ordinal + ORD_OFFSET );
225
+ absdate = ordinal + ORD_OFFSET ;
226
+ dInfoCalc_SetFromAbsDate (& dinfo , absdate );
232
227
233
228
// This usage defines roll_back the opposite way from the others
234
229
roll_back = 1 - af_info -> is_end ;
235
- return DtoB (& dinfo , roll_back );
230
+ return DtoB (& dinfo , roll_back , absdate );
236
231
}
237
232
238
233
// 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) {
298
293
299
294
static npy_int64 asfreq_WtoB (npy_int64 ordinal , asfreq_info * af_info ) {
300
295
struct date_info dinfo ;
296
+ npy_int64 absdate = asfreq_WtoDT (ordinal , af_info ) + ORD_OFFSET ;
301
297
int roll_back = af_info -> is_end ;
302
- dInfoCalc_SetFromAbsDate (
303
- & dinfo , asfreq_WtoDT (ordinal , af_info ) + ORD_OFFSET );
298
+ dInfoCalc_SetFromAbsDate (& dinfo , absdate );
304
299
305
- return DtoB (& dinfo , roll_back );
300
+ return DtoB (& dinfo , roll_back , absdate );
306
301
}
307
302
308
303
//************ FROM MONTHLY ***************
@@ -338,12 +333,12 @@ static npy_int64 asfreq_MtoW(npy_int64 ordinal, asfreq_info *af_info) {
338
333
339
334
static npy_int64 asfreq_MtoB (npy_int64 ordinal , asfreq_info * af_info ) {
340
335
struct date_info dinfo ;
336
+ npy_int64 absdate = asfreq_MtoDT (ordinal , af_info ) + ORD_OFFSET ;
341
337
int roll_back = af_info -> is_end ;
342
338
343
- dInfoCalc_SetFromAbsDate (
344
- & dinfo , asfreq_MtoDT (ordinal , af_info ) + ORD_OFFSET );
339
+ dInfoCalc_SetFromAbsDate (& dinfo , absdate );
345
340
346
- return DtoB (& dinfo , roll_back );
341
+ return DtoB (& dinfo , roll_back , absdate );
347
342
}
348
343
349
344
//************ FROM QUARTERLY ***************
@@ -393,12 +388,12 @@ static npy_int64 asfreq_QtoW(npy_int64 ordinal, asfreq_info *af_info) {
393
388
394
389
static npy_int64 asfreq_QtoB (npy_int64 ordinal , asfreq_info * af_info ) {
395
390
struct date_info dinfo ;
391
+ npy_int64 absdate = asfreq_QtoDT (ordinal , af_info ) + ORD_OFFSET ;
396
392
int roll_back = af_info -> is_end ;
397
393
398
- dInfoCalc_SetFromAbsDate (
399
- & dinfo , asfreq_QtoDT (ordinal , af_info ) + ORD_OFFSET );
394
+ dInfoCalc_SetFromAbsDate (& dinfo , absdate );
400
395
401
- return DtoB (& dinfo , roll_back );
396
+ return DtoB (& dinfo , roll_back , absdate );
402
397
}
403
398
404
399
//************ FROM ANNUAL ***************
@@ -439,11 +434,11 @@ static npy_int64 asfreq_AtoW(npy_int64 ordinal, asfreq_info *af_info) {
439
434
440
435
static npy_int64 asfreq_AtoB (npy_int64 ordinal , asfreq_info * af_info ) {
441
436
struct date_info dinfo ;
437
+ npy_int64 absdate = asfreq_AtoDT (ordinal , af_info ) + ORD_OFFSET ;
442
438
int roll_back = af_info -> is_end ;
443
- dInfoCalc_SetFromAbsDate (
444
- & dinfo , asfreq_AtoDT (ordinal , af_info ) + ORD_OFFSET );
439
+ dInfoCalc_SetFromAbsDate (& dinfo , absdate );
445
440
446
- return DtoB (& dinfo , roll_back );
441
+ return DtoB (& dinfo , roll_back , absdate );
447
442
}
448
443
449
444
static npy_int64 nofunc (npy_int64 ordinal , asfreq_info * af_info ) {
@@ -675,65 +670,6 @@ freq_conv_func get_asfreq_func(int fromFreq, int toFreq) {
675
670
}
676
671
}
677
672
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
-
737
673
/* ------------------------------------------------------------------
738
674
* New pandas API-helper code, to expose to cython
739
675
* ------------------------------------------------------------------*/
@@ -750,185 +686,3 @@ npy_int64 asfreq(npy_int64 period_ordinal, int freq1, int freq2,
750
686
val = (* func )(period_ordinal , & finfo );
751
687
return val ;
752
688
}
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