@@ -430,7 +430,31 @@ cpdef datetime shift_month(datetime stamp, int months, object day_opt=None):
430
430
return stamp.replace(year = year, month = month, day = day)
431
431
432
432
433
- cpdef int _get_day_of_month(datetime other, day_opt):
433
+ cdef int get_day_of_month(datetime other, day_opt):
434
+ """
435
+ Find the day in `other`'s month that satisfies a DateOffset's onOffset
436
+ policy, as described by the `day_opt` argument.
437
+
438
+ Parameters
439
+ ----------
440
+ other : datetime or Timestamp
441
+ day_opt : 'start', 'end'
442
+ 'start': returns 1
443
+ 'end': returns last day of the month
444
+
445
+ Returns
446
+ -------
447
+ day_of_month : int
448
+
449
+ Examples
450
+ -------
451
+ >>> other = datetime(2017, 11, 14)
452
+ >>> get_day_of_month(other, 'start')
453
+ 1
454
+ >>> get_day_of_month(other, 'end')
455
+ 30
456
+
457
+ """
434
458
if day_opt == ' start' :
435
459
return 1
436
460
elif day_opt == ' end' :
@@ -444,20 +468,65 @@ cpdef int roll_yearday(other, n, month, day_opt='start'):
444
468
Possibly increment or decrement the number of periods to shift
445
469
based on rollforward/rollbackward conventions.
446
470
447
- Mirrors `roll_check` in tslib.shift_months
471
+ Parameters
472
+ ----------
473
+ other : datetime or Timestamp
474
+ n : number of periods to increment, before adjusting for rolling
475
+ day_opt : 'start', 'end'
476
+ 'start': returns 1
477
+ 'end': returns last day of the month
478
+
479
+ Returns
480
+ -------
481
+ n : int number of periods to increment
482
+
483
+ Notes
484
+ -----
485
+ * Mirrors `roll_check` in tslib.shift_months
486
+
487
+ Examples
488
+ -------
489
+ >>> month = 3
490
+ >>> day_opt = 'start' # `other` will be compared to March 1
491
+ >>> other = datetime(2017, 2, 10) # before March 1
492
+ >>> roll_yearday(other, 2, month, day_opt)
493
+ 1
494
+ >>> roll_yearday(other, -7, month, day_opt)
495
+ -7
496
+ >>>
497
+ >>> other = Timestamp('2014-03-15', tz='US/Eastern') # after March 1
498
+ >>> roll_yearday(other, 2, month, day_opt)
499
+ 2
500
+ >>> roll_yearday(other, -7, month, day_opt)
501
+ -6
502
+
503
+ >>> month = 6
504
+ >>> day_opt = 'end' # `other` will be compared to June 30
505
+ >>> other = datetime(1999, 6, 29) # before June 30
506
+ >>> roll_yearday(other, 5, month, day_opt)
507
+ 4
508
+ >>> roll_yearday(other, -7, month, day_opt)
509
+ -7
510
+ >>>
511
+ >>> other = Timestamp(2072, 8, 24, 6, 17, 18) # after June 30
512
+ >>> roll_yearday(other, 5, month, day_opt)
513
+ 5
514
+ >>> roll_yearday(other, -7, month, day_opt)
515
+ -6
516
+
448
517
"""
449
518
# Note: The other.day < ... condition will never hold when day_opt=='start'
450
519
# and the other.day > ... condition will never hold when day_opt=='end'.
451
520
# At some point these extra checks may need to be optimized away.
452
521
# But that point isn't today.
453
522
if n > 0 :
454
523
if other.month < month or (other.month == month and
455
- other.day < _get_day_of_month (other,
456
- day_opt)):
524
+ other.day < get_day_of_month (other,
525
+ day_opt)):
457
526
n -= 1
458
527
elif n <= 0 :
459
528
if other.month > month or (other.month == month and
460
- other.day > _get_day_of_month (other,
461
- day_opt)):
529
+ other.day > get_day_of_month (other,
530
+ day_opt)):
462
531
n += 1
463
532
return n
0 commit comments