1313
1414from pandas import _np_version_under1p7
1515
16+ import functools
17+
1618__all__ = ['Day' , 'BusinessDay' , 'BDay' , 'CustomBusinessDay' , 'CDay' ,
1719 'MonthBegin' , 'BMonthBegin' , 'MonthEnd' , 'BMonthEnd' ,
1820 'YearBegin' , 'BYearBegin' , 'YearEnd' , 'BYearEnd' ,
@@ -35,6 +37,15 @@ def as_datetime(obj):
3537 obj = f ()
3638 return obj
3739
40+ def apply_nat (func ):
41+ @functools .wraps (func )
42+ def wrapper (self , other ):
43+ if other is tslib .NaT :
44+ return tslib .NaT
45+ else :
46+ return func (self , other )
47+ return wrapper
48+
3849#----------------------------------------------------------------------
3950# DateOffset
4051
@@ -102,6 +113,7 @@ def __init__(self, n=1, **kwds):
102113 else :
103114 self ._offset = timedelta (1 )
104115
116+ @apply_nat
105117 def apply (self , other ):
106118 other = as_datetime (other )
107119 if len (self .kwds ) > 0 :
@@ -382,6 +394,7 @@ def get_str(td):
382394 def isAnchored (self ):
383395 return (self .n == 1 )
384396
397+ @apply_nat
385398 def apply (self , other ):
386399 if isinstance (other , datetime ):
387400 n = self .n
@@ -502,6 +515,7 @@ def __setstate__(self, state):
502515 self .__dict__ = state
503516 self ._set_busdaycalendar ()
504517
518+ @apply_nat
505519 def apply (self , other ):
506520 if self .n <= 0 :
507521 roll = 'forward'
@@ -582,6 +596,7 @@ def name(self):
582596class MonthEnd (MonthOffset ):
583597 """DateOffset of one month end"""
584598
599+ @apply_nat
585600 def apply (self , other ):
586601 other = datetime (other .year , other .month , other .day ,
587602 tzinfo = other .tzinfo )
@@ -606,6 +621,7 @@ def onOffset(cls, dt):
606621class MonthBegin (MonthOffset ):
607622 """DateOffset of one month at beginning"""
608623
624+ @apply_nat
609625 def apply (self , other ):
610626 n = self .n
611627
@@ -628,6 +644,7 @@ class BusinessMonthEnd(MonthOffset):
628644 def isAnchored (self ):
629645 return (self .n == 1 )
630646
647+ @apply_nat
631648 def apply (self , other ):
632649 other = datetime (other .year , other .month , other .day )
633650
@@ -653,6 +670,7 @@ def apply(self, other):
653670class BusinessMonthBegin (MonthOffset ):
654671 """DateOffset of one business month at beginning"""
655672
673+ @apply_nat
656674 def apply (self , other ):
657675 n = self .n
658676
@@ -710,6 +728,7 @@ def __init__(self, n=1, **kwds):
710728 def isAnchored (self ):
711729 return (self .n == 1 and self .weekday is not None )
712730
731+ @apply_nat
713732 def apply (self , other ):
714733 if self .weekday is None :
715734 return as_timestamp (as_datetime (other ) + self .n * self ._inc )
@@ -811,6 +830,7 @@ def __init__(self, n=1, **kwds):
811830
812831 self .kwds = kwds
813832
833+ @apply_nat
814834 def apply (self , other ):
815835 offsetOfMonth = self .getOffsetOfMonth (other )
816836
@@ -890,6 +910,7 @@ def __init__(self, n=1, **kwds):
890910
891911 self .kwds = kwds
892912
913+ @apply_nat
893914 def apply (self , other ):
894915 offsetOfMonth = self .getOffsetOfMonth (other )
895916
@@ -983,6 +1004,7 @@ class BQuarterEnd(QuarterOffset):
9831004 _from_name_startingMonth = 12
9841005 _prefix = 'BQ'
9851006
1007+ @apply_nat
9861008 def apply (self , other ):
9871009 n = self .n
9881010
@@ -1037,6 +1059,7 @@ class BQuarterBegin(QuarterOffset):
10371059 _from_name_startingMonth = 1
10381060 _prefix = 'BQS'
10391061
1062+ @apply_nat
10401063 def apply (self , other ):
10411064 n = self .n
10421065 other = as_datetime (other )
@@ -1086,6 +1109,7 @@ def __init__(self, n=1, **kwds):
10861109 def isAnchored (self ):
10871110 return (self .n == 1 and self .startingMonth is not None )
10881111
1112+ @apply_nat
10891113 def apply (self , other ):
10901114 n = self .n
10911115 other = as_datetime (other )
@@ -1117,6 +1141,7 @@ class QuarterBegin(QuarterOffset):
11171141 def isAnchored (self ):
11181142 return (self .n == 1 and self .startingMonth is not None )
11191143
1144+ @apply_nat
11201145 def apply (self , other ):
11211146 n = self .n
11221147 other = as_datetime (other )
@@ -1166,6 +1191,7 @@ class BYearEnd(YearOffset):
11661191 _default_month = 12
11671192 _prefix = 'BA'
11681193
1194+ @apply_nat
11691195 def apply (self , other ):
11701196 n = self .n
11711197 other = as_datetime (other )
@@ -1203,6 +1229,7 @@ class BYearBegin(YearOffset):
12031229 _default_month = 1
12041230 _prefix = 'BAS'
12051231
1232+ @apply_nat
12061233 def apply (self , other ):
12071234 n = self .n
12081235 other = as_datetime (other )
@@ -1234,6 +1261,7 @@ class YearEnd(YearOffset):
12341261 _default_month = 12
12351262 _prefix = 'A'
12361263
1264+ @apply_nat
12371265 def apply (self , other ):
12381266 def _increment (date ):
12391267 if date .month == self .month :
@@ -1290,6 +1318,7 @@ class YearBegin(YearOffset):
12901318 _default_month = 1
12911319 _prefix = 'AS'
12921320
1321+ @apply_nat
12931322 def apply (self , other ):
12941323 def _increment (date ):
12951324 year = date .year
@@ -1410,6 +1439,7 @@ def onOffset(self, dt):
14101439 else :
14111440 return year_end == dt
14121441
1442+ @apply_nat
14131443 def apply (self , other ):
14141444 n = self .n
14151445 prev_year = self .get_year_end (
@@ -1596,6 +1626,7 @@ def __init__(self, n=1, **kwds):
15961626 def isAnchored (self ):
15971627 return self .n == 1 and self ._offset .isAnchored ()
15981628
1629+ @apply_nat
15991630 def apply (self , other ):
16001631 other = as_datetime (other )
16011632 n = self .n
@@ -1693,6 +1724,7 @@ class Easter(DateOffset):
16931724 def __init__ (self , n = 1 , ** kwds ):
16941725 super (Easter , self ).__init__ (n , ** kwds )
16951726
1727+ @apply_nat
16961728 def apply (self , other ):
16971729
16981730 currentEaster = easter (other .year )
@@ -1786,6 +1818,7 @@ def delta(self):
17861818 def nanos (self ):
17871819 return _delta_to_nanoseconds (self .delta )
17881820
1821+ @apply_nat
17891822 def apply (self , other ):
17901823 if type (other ) == date :
17911824 other = datetime (other .year , other .month , other .day )
0 commit comments