@@ -154,12 +154,32 @@ cdef inline int get_freq_group(int freq) nogil:
154
154
return (freq // 1000 ) * 1000
155
155
156
156
157
- @cython.cdivision
157
+ # specifically _dont_ use cdvision or else ordinals near -1 are assigned to
158
+ # incorrect dates GH#19643
159
+ @ cython.cdivision (False )
158
160
cdef int64_t get_period_ordinal(int year, int month, int day,
159
161
int hour, int minute, int second,
160
162
int microseconds, int picoseconds,
161
163
int freq) nogil:
162
- """ generate an ordinal in period space"""
164
+ """
165
+ Generate an ordinal in period space
166
+
167
+ Parameters
168
+ ----------
169
+ year : int
170
+ month : int
171
+ day : int
172
+ hour : int
173
+ minute : int
174
+ second : int
175
+ microseconds : int
176
+ picoseconds : int
177
+ freq : int
178
+
179
+ Returns
180
+ -------
181
+ period_ordinal : int64_t
182
+ """
163
183
cdef:
164
184
int64_t absdays, unix_date, seconds, delta
165
185
int64_t weeks
@@ -190,7 +210,7 @@ cdef int64_t get_period_ordinal(int year, int month, int day,
190
210
if month >= fmonth:
191
211
mdiff += 12
192
212
193
- return (year - 1970 ) * 4 + (mdiff - 1 ) / 3
213
+ return (year - 1970 ) * 4 + (mdiff - 1 ) // 3
194
214
195
215
elif freq == FR_MTH:
196
216
return (year - 1970 ) * 12 + month - 1
@@ -202,14 +222,14 @@ cdef int64_t get_period_ordinal(int year, int month, int day,
202
222
seconds = unix_date * 86400 + hour * 3600 + minute * 60 + second
203
223
204
224
if freq == FR_MS:
205
- return seconds * 1000 + microseconds / 1000
225
+ return seconds * 1000 + microseconds // 1000
206
226
207
227
elif freq == FR_US:
208
228
return seconds * 1000000 + microseconds
209
229
210
230
elif freq == FR_NS:
211
231
return (seconds * 1000000000 +
212
- microseconds * 1000 + picoseconds / 1000 )
232
+ microseconds * 1000 + picoseconds // 1000 )
213
233
214
234
else :
215
235
return seconds
@@ -229,7 +249,7 @@ cdef int64_t get_period_ordinal(int year, int month, int day,
229
249
elif freq == FR_BUS:
230
250
# calculate the current week assuming sunday as last day of a week
231
251
# Jan 1 0001 is a Monday, so subtract 1 to get to end-of-week
232
- weeks = (unix_date + ORD_OFFSET - 1 ) / 7
252
+ weeks = (unix_date + ORD_OFFSET - 1 ) // 7
233
253
# calculate the current weekday (in range 1 .. 7)
234
254
delta = (unix_date + ORD_OFFSET - 1 ) % 7 + 1
235
255
# return the number of business days in full weeks plus the business
@@ -241,12 +261,12 @@ cdef int64_t get_period_ordinal(int year, int month, int day,
241
261
242
262
elif freq_group == FR_WK:
243
263
day_adj = freq - FR_WK
244
- return (unix_date + ORD_OFFSET - (1 + day_adj)) / 7 + 1 - WEEK_OFFSET
264
+ return (unix_date + ORD_OFFSET - (1 + day_adj)) // 7 + 1 - WEEK_OFFSET
245
265
246
266
# raise ValueError
247
267
248
268
249
- cdef int get_date_info(int64_t ordinal, int freq, date_info * dinfo) nogil:
269
+ cdef void get_date_info(int64_t ordinal, int freq, date_info * dinfo) nogil:
250
270
cdef:
251
271
int64_t absdate
252
272
double abstime
@@ -263,7 +283,6 @@ cdef int get_date_info(int64_t ordinal, int freq, date_info *dinfo) nogil:
263
283
absdate += 1
264
284
265
285
dInfoCalc_SetFromAbsDateTime(dinfo, absdate, abstime)
266
- return 0
267
286
268
287
269
288
cdef int64_t get_python_ordinal(int64_t period_ordinal, int freq) nogil:
@@ -272,6 +291,15 @@ cdef int64_t get_python_ordinal(int64_t period_ordinal, int freq) nogil:
272
291
This corresponds to the number of days since Jan., 1st, 1AD.
273
292
When the instance has a frequency less than daily, the proleptic date
274
293
is calculated for the last day of the period.
294
+
295
+ Parameters
296
+ ----------
297
+ period_ordinal : int64_t
298
+ freq : int
299
+
300
+ Returns
301
+ -------
302
+ absdate : int64_t number of days since datetime(1, 1, 1)
275
303
"""
276
304
cdef:
277
305
asfreq_info af_info
@@ -285,11 +313,23 @@ cdef int64_t get_python_ordinal(int64_t period_ordinal, int freq) nogil:
285
313
return toDaily(period_ordinal, & af_info) + ORD_OFFSET
286
314
287
315
288
- cdef int dInfoCalc_SetFromAbsDateTime(date_info * dinfo,
289
- int64_t absdate, double abstime) nogil:
316
+ cdef void dInfoCalc_SetFromAbsDateTime(date_info * dinfo,
317
+ int64_t absdate, double abstime) nogil:
290
318
"""
291
319
Set the instance's value using the given date and time.
292
320
Assumes GREGORIAN_CALENDAR.
321
+
322
+ Parameters
323
+ ----------
324
+ dinfo : date_info*
325
+ absdate : int64_t
326
+ days elapsed since datetime(1, 1, 1)
327
+ abstime : double
328
+ seconds elapsed since beginning of day described by absdate
329
+
330
+ Notes
331
+ -----
332
+ Updates dinfo inplace
293
333
"""
294
334
# Bounds check
295
335
# The calling function is responsible for ensuring that
@@ -300,13 +340,21 @@ cdef int dInfoCalc_SetFromAbsDateTime(date_info *dinfo,
300
340
301
341
# Calculate the time
302
342
dInfoCalc_SetFromAbsTime(dinfo, abstime)
303
- return 0
304
343
305
344
306
- cdef int dInfoCalc_SetFromAbsDate(date_info * dinfo, int64_t absdate) nogil:
345
+ cdef void dInfoCalc_SetFromAbsDate(date_info * dinfo, int64_t absdate) nogil:
307
346
"""
308
347
Sets the date part of the date_info struct
309
348
Assumes GREGORIAN_CALENDAR
349
+
350
+ Parameters
351
+ ----------
352
+ dinfo : date_info*
353
+ unix_date : int64_t
354
+
355
+ Notes
356
+ -----
357
+ Updates dinfo inplace
310
358
"""
311
359
cdef:
312
360
pandas_datetimestruct dts
@@ -315,13 +363,22 @@ cdef int dInfoCalc_SetFromAbsDate(date_info *dinfo, int64_t absdate) nogil:
315
363
dinfo.year = dts.year
316
364
dinfo.month = dts.month
317
365
dinfo.day = dts.day
318
- return 0
319
366
320
367
321
368
@cython.cdivision
322
- cdef int dInfoCalc_SetFromAbsTime(date_info * dinfo, double abstime) nogil:
369
+ cdef void dInfoCalc_SetFromAbsTime(date_info * dinfo, double abstime) nogil:
323
370
"""
324
371
Sets the time part of the DateTime object.
372
+
373
+ Parameters
374
+ ----------
375
+ dinfo : date_info*
376
+ abstime : double
377
+ seconds elapsed since beginning of day described by absdate
378
+
379
+ Notes
380
+ -----
381
+ Updates dinfo inplace
325
382
"""
326
383
cdef:
327
384
int inttime
@@ -336,7 +393,6 @@ cdef int dInfoCalc_SetFromAbsTime(date_info *dinfo, double abstime) nogil:
336
393
dinfo.hour = hour
337
394
dinfo.minute = minute
338
395
dinfo.second = second
339
- return 0
340
396
341
397
342
398
@cython.cdivision
@@ -370,7 +426,19 @@ cdef int64_t absdate_from_ymd(int year, int month, int day) nogil:
370
426
Find the absdate (days elapsed since datetime(1, 1, 1)
371
427
for the given year/month/day.
372
428
Assumes GREGORIAN_CALENDAR
429
+
430
+ Parameters
431
+ ----------
432
+ year : int
433
+ month : int
434
+ day : int
435
+
436
+ Returns
437
+ -------
438
+ absdate : int
439
+ days elapsed since datetime(1, 1, 1)
373
440
"""
441
+
374
442
# /* Calculate the absolute date
375
443
cdef:
376
444
pandas_datetimestruct dts
@@ -385,6 +453,25 @@ cdef int64_t absdate_from_ymd(int year, int month, int day) nogil:
385
453
386
454
387
455
cdef int get_yq(int64_t ordinal, int freq, int * quarter, int * year):
456
+ """
457
+ Find the year and quarter of a Period with the given ordinal and frequency
458
+
459
+ Parameters
460
+ ----------
461
+ ordinal : int64_t
462
+ freq : int
463
+ quarter : *int
464
+ year : *int
465
+
466
+ Returns
467
+ -------
468
+ qtr_freq : int
469
+ describes the implied quarterly frequency associated with `freq`
470
+
471
+ Notes
472
+ -----
473
+ Sets quarter and year inplace
474
+ """
388
475
cdef:
389
476
asfreq_info af_info
390
477
int qtr_freq
@@ -403,8 +490,8 @@ cdef int get_yq(int64_t ordinal, int freq, int *quarter, int *year):
403
490
return qtr_freq
404
491
405
492
406
- cdef int64_t DtoQ_yq(int64_t ordinal, asfreq_info * af_info,
407
- int * year, int * quarter):
493
+ cdef void DtoQ_yq(int64_t ordinal, asfreq_info * af_info,
494
+ int * year, int * quarter):
408
495
cdef:
409
496
date_info dinfo
410
497
@@ -419,7 +506,6 @@ cdef int64_t DtoQ_yq(int64_t ordinal, asfreq_info *af_info,
419
506
420
507
year[0 ] = dinfo.year
421
508
quarter[0 ] = monthToQuarter(dinfo.month)
422
- return 0
423
509
424
510
425
511
cdef inline int monthToQuarter(int month):
0 commit comments