18
18
__all__ = ['Day' , 'BusinessDay' , 'BDay' , 'CustomBusinessDay' , 'CDay' ,
19
19
'CBMonthEnd' , 'CBMonthBegin' ,
20
20
'MonthBegin' , 'BMonthBegin' , 'MonthEnd' , 'BMonthEnd' ,
21
- 'BusinessHour' ,
21
+ 'BusinessHour' , 'CustomBusinessHour' ,
22
22
'YearBegin' , 'BYearBegin' , 'YearEnd' , 'BYearEnd' ,
23
23
'QuarterBegin' , 'BQuarterBegin' , 'QuarterEnd' , 'BQuarterEnd' ,
24
24
'LastWeekOfMonth' , 'FY5253Quarter' , 'FY5253' ,
@@ -669,20 +669,9 @@ def onOffset(self, dt):
669
669
return dt .weekday () < 5
670
670
671
671
672
- class BusinessHour (BusinessMixin , SingleConstructorOffset ):
673
- """
674
- DateOffset subclass representing possibly n business days
675
-
676
- .. versionadded: 0.16.1
677
-
678
- """
679
- _prefix = 'BH'
680
- _anchor = 0
681
-
682
- def __init__ (self , n = 1 , normalize = False , ** kwds ):
683
- self .n = int (n )
684
- self .normalize = normalize
672
+ class BusinessHourMixin (BusinessMixin ):
685
673
674
+ def __init__ (self , ** kwds ):
686
675
# must be validated here to equality check
687
676
kwds ['start' ] = self ._validate_time (kwds .get ('start' , '09:00' ))
688
677
kwds ['end' ] = self ._validate_time (kwds .get ('end' , '17:00' ))
@@ -691,12 +680,6 @@ def __init__(self, n=1, normalize=False, **kwds):
691
680
self .start = kwds .get ('start' , '09:00' )
692
681
self .end = kwds .get ('end' , '17:00' )
693
682
694
- # used for moving to next businessday
695
- if self .n >= 0 :
696
- self .next_bday = BusinessDay (n = 1 )
697
- else :
698
- self .next_bday = BusinessDay (n = - 1 )
699
-
700
683
def _validate_time (self , t_input ):
701
684
from datetime import time as dt_time
702
685
import time
@@ -722,13 +705,6 @@ def _get_daytime_flag(self):
722
705
else :
723
706
return False
724
707
725
- def _repr_attrs (self ):
726
- out = super (BusinessHour , self )._repr_attrs ()
727
- attrs = ['BH=%s-%s' % (self .start .strftime ('%H:%M' ),
728
- self .end .strftime ('%H:%M' ))]
729
- out += ': ' + ', ' .join (attrs )
730
- return out
731
-
732
708
def _next_opening_time (self , other ):
733
709
"""
734
710
If n is positive, return tomorrow's business day opening time.
@@ -905,6 +881,38 @@ def _onOffset(self, dt, businesshours):
905
881
else :
906
882
return False
907
883
884
+ def _repr_attrs (self ):
885
+ out = super (BusinessHourMixin , self )._repr_attrs ()
886
+ start = self .start .strftime ('%H:%M' )
887
+ end = self .end .strftime ('%H:%M' )
888
+ attrs = ['{prefix}={start}-{end}' .format (prefix = self ._prefix ,
889
+ start = start , end = end )]
890
+ out += ': ' + ', ' .join (attrs )
891
+ return out
892
+
893
+
894
+ class BusinessHour (BusinessHourMixin , SingleConstructorOffset ):
895
+ """
896
+ DateOffset subclass representing possibly n business days
897
+
898
+ .. versionadded: 0.16.1
899
+
900
+ """
901
+ _prefix = 'BH'
902
+ _anchor = 0
903
+
904
+ def __init__ (self , n = 1 , normalize = False , ** kwds ):
905
+ self .n = int (n )
906
+ self .normalize = normalize
907
+ super (BusinessHour , self ).__init__ (** kwds )
908
+
909
+ # used for moving to next businessday
910
+ if self .n >= 0 :
911
+ nb_offset = 1
912
+ else :
913
+ nb_offset = - 1
914
+ self .next_bday = BusinessDay (n = nb_offset )
915
+
908
916
909
917
class CustomBusinessDay (BusinessDay ):
910
918
"""
@@ -976,18 +984,7 @@ def get_calendar(self, weekmask, holidays, calendar):
976
984
if holidays :
977
985
kwargs ['holidays' ] = holidays
978
986
979
- try :
980
- busdaycalendar = np .busdaycalendar (** kwargs )
981
- except :
982
- # Check we have the required numpy version
983
- from distutils .version import LooseVersion
984
-
985
- if LooseVersion (np .__version__ ) < '1.7.0' :
986
- raise NotImplementedError (
987
- "CustomBusinessDay requires numpy >= "
988
- "1.7.0. Current version: " + np .__version__ )
989
- else :
990
- raise
987
+ busdaycalendar = np .busdaycalendar (** kwargs )
991
988
return busdaycalendar , holidays
992
989
993
990
def __getstate__ (self ):
@@ -1067,6 +1064,36 @@ def onOffset(self, dt):
1067
1064
return np .is_busday (day64 , busdaycal = self .calendar )
1068
1065
1069
1066
1067
+ class CustomBusinessHour (BusinessHourMixin , SingleConstructorOffset ):
1068
+ """
1069
+ DateOffset subclass representing possibly n custom business days
1070
+
1071
+ .. versionadded: 0.18.1
1072
+
1073
+ """
1074
+ _prefix = 'CBH'
1075
+ _anchor = 0
1076
+
1077
+ def __init__ (self , n = 1 , normalize = False , weekmask = 'Mon Tue Wed Thu Fri' ,
1078
+ holidays = None , calendar = None , ** kwds ):
1079
+ self .n = int (n )
1080
+ self .normalize = normalize
1081
+ super (CustomBusinessHour , self ).__init__ (** kwds )
1082
+ # used for moving to next businessday
1083
+ if self .n >= 0 :
1084
+ nb_offset = 1
1085
+ else :
1086
+ nb_offset = - 1
1087
+ self .next_bday = CustomBusinessDay (n = nb_offset ,
1088
+ weekmask = weekmask ,
1089
+ holidays = holidays ,
1090
+ calendar = calendar )
1091
+
1092
+ self .kwds ['weekmask' ] = self .next_bday .weekmask
1093
+ self .kwds ['holidays' ] = self .next_bday .holidays
1094
+ self .kwds ['calendar' ] = self .next_bday .calendar
1095
+
1096
+
1070
1097
class MonthOffset (SingleConstructorOffset ):
1071
1098
_adjust_dst = True
1072
1099
@@ -2673,31 +2700,32 @@ def generate_range(start=None, end=None, periods=None,
2673
2700
cur = next_date
2674
2701
2675
2702
prefix_mapping = dict ((offset ._prefix , offset ) for offset in [
2676
- YearBegin , # 'AS'
2677
- YearEnd , # 'A'
2678
- BYearBegin , # 'BAS'
2679
- BYearEnd , # 'BA'
2680
- BusinessDay , # 'B'
2681
- BusinessMonthBegin , # 'BMS'
2682
- BusinessMonthEnd , # 'BM'
2683
- BQuarterEnd , # 'BQ'
2684
- BQuarterBegin , # 'BQS'
2685
- BusinessHour , # 'BH'
2686
- CustomBusinessDay , # 'C'
2687
- CustomBusinessMonthEnd , # 'CBM'
2703
+ YearBegin , # 'AS'
2704
+ YearEnd , # 'A'
2705
+ BYearBegin , # 'BAS'
2706
+ BYearEnd , # 'BA'
2707
+ BusinessDay , # 'B'
2708
+ BusinessMonthBegin , # 'BMS'
2709
+ BusinessMonthEnd , # 'BM'
2710
+ BQuarterEnd , # 'BQ'
2711
+ BQuarterBegin , # 'BQS'
2712
+ BusinessHour , # 'BH'
2713
+ CustomBusinessDay , # 'C'
2714
+ CustomBusinessMonthEnd , # 'CBM'
2688
2715
CustomBusinessMonthBegin , # 'CBMS'
2689
- MonthEnd , # 'M'
2690
- MonthBegin , # 'MS'
2691
- Week , # 'W'
2692
- Second , # 'S'
2693
- Minute , # 'T'
2694
- Micro , # 'U'
2695
- QuarterEnd , # 'Q'
2696
- QuarterBegin , # 'QS'
2697
- Milli , # 'L'
2698
- Hour , # 'H'
2699
- Day , # 'D'
2700
- WeekOfMonth , # 'WOM'
2716
+ CustomBusinessHour , # 'CBH'
2717
+ MonthEnd , # 'M'
2718
+ MonthBegin , # 'MS'
2719
+ Week , # 'W'
2720
+ Second , # 'S'
2721
+ Minute , # 'T'
2722
+ Micro , # 'U'
2723
+ QuarterEnd , # 'Q'
2724
+ QuarterBegin , # 'QS'
2725
+ Milli , # 'L'
2726
+ Hour , # 'H'
2727
+ Day , # 'D'
2728
+ WeekOfMonth , # 'WOM'
2701
2729
FY5253 ,
2702
2730
FY5253Quarter ,
2703
2731
])
0 commit comments