@@ -29,7 +29,12 @@ class HourlyInterval(object):
2929 def __init__ (self , start_time , end_time , interval_value ):
3030 self .start_time = start_time
3131 self .end_time = end_time
32- self .interval = interval_value
32+
33+ # interval should be a tuple, if it is not, assign as a tuple with single value
34+ if isinstance (interval_value , tuple ):
35+ self .interval = interval_value
36+ else :
37+ self .interval = (interval_value ,)
3338
3439 def __repr__ (self ):
3540 return f"<{ self .__class__ .__name__ } start={ self .start_time } end={ self .end_time } interval={ self .interval } >"
@@ -63,25 +68,44 @@ def interval(self):
6368 return self ._interval
6469
6570 @interval .setter
66- def interval (self , interval ):
71+ def interval (self , intervals ):
6772 VALID_INTERVALS = {0.25 , 0.5 , 1 , 2 , 4 , 6 , 8 , 12 }
68- if float (interval ) not in VALID_INTERVALS :
69- error = "Invalid interval {} not in {}" .format (interval , str (VALID_INTERVALS ))
70- raise ValueError (error )
73+ for interval in intervals :
74+ # if an hourly interval is a string, then it is a weekDay interval
75+ if isinstance (interval , str ) and not interval .isnumeric () and not hasattr (IntervalItem .Day , interval ):
76+ error = "Invalid weekDay interval {}" .format (interval )
77+ raise ValueError (error )
78+
79+ # if an hourly interval is a number, it is an hours or minutes interval
80+ if isinstance (interval , (int , float )) and float (interval ) not in VALID_INTERVALS :
81+ error = "Invalid interval {} not in {}" .format (interval , str (VALID_INTERVALS ))
82+ raise ValueError (error )
7183
72- self ._interval = interval
84+ self ._interval = intervals
7385
7486 def _interval_type_pairs (self ):
75- # We use fractional hours for the two minute-based intervals.
76- # Need to convert to minutes from hours here
77- if self .interval in {0.25 , 0.5 }:
78- calculated_interval = int (self .interval * 60 )
79- interval_type = IntervalItem .Occurrence .Minutes
80- else :
81- calculated_interval = self .interval
82- interval_type = IntervalItem .Occurrence .Hours
87+ interval_type_pairs = []
88+ for interval in self .interval :
89+ # We use fractional hours for the two minute-based intervals.
90+ # Need to convert to minutes from hours here
91+ if interval in {0.25 , 0.5 }:
92+ calculated_interval = int (interval * 60 )
93+ interval_type = IntervalItem .Occurrence .Minutes
94+
95+ interval_type_pairs .append ((interval_type , str (calculated_interval )))
96+ else :
97+ # if the interval is a non-numeric string, it will always be a weekDay
98+ if isinstance (interval , str ) and not interval .isnumeric ():
99+ interval_type = IntervalItem .Occurrence .WeekDay
100+
101+ interval_type_pairs .append ((interval_type , str (interval )))
102+ # otherwise the interval is hours
103+ else :
104+ interval_type = IntervalItem .Occurrence .Hours
83105
84- return [(interval_type , str (calculated_interval ))]
106+ interval_type_pairs .append ((interval_type , str (interval )))
107+
108+ return interval_type_pairs
85109
86110
87111class DailyInterval (object ):
@@ -111,8 +135,45 @@ def interval(self):
111135 return self ._interval
112136
113137 @interval .setter
114- def interval (self , interval ):
115- self ._interval = interval
138+ def interval (self , intervals ):
139+ VALID_INTERVALS = {0.25 , 0.5 , 1 , 2 , 4 , 6 , 8 , 12 }
140+
141+ for interval in intervals :
142+ # if an hourly interval is a string, then it is a weekDay interval
143+ if isinstance (interval , str ) and not interval .isnumeric () and not hasattr (IntervalItem .Day , interval ):
144+ error = "Invalid weekDay interval {}" .format (interval )
145+ raise ValueError (error )
146+
147+ # if an hourly interval is a number, it is an hours or minutes interval
148+ if isinstance (interval , (int , float )) and float (interval ) not in VALID_INTERVALS :
149+ error = "Invalid interval {} not in {}" .format (interval , str (VALID_INTERVALS ))
150+ raise ValueError (error )
151+
152+ self ._interval = intervals
153+
154+ def _interval_type_pairs (self ):
155+ interval_type_pairs = []
156+ for interval in self .interval :
157+ # We use fractional hours for the two minute-based intervals.
158+ # Need to convert to minutes from hours here
159+ if interval in {0.25 , 0.5 }:
160+ calculated_interval = int (interval * 60 )
161+ interval_type = IntervalItem .Occurrence .Minutes
162+
163+ interval_type_pairs .append ((interval_type , str (calculated_interval )))
164+ else :
165+ # if the interval is a non-numeric string, it will always be a weekDay
166+ if isinstance (interval , str ) and not interval .isnumeric ():
167+ interval_type = IntervalItem .Occurrence .WeekDay
168+
169+ interval_type_pairs .append ((interval_type , str (interval )))
170+ # otherwise the interval is hours
171+ else :
172+ interval_type = IntervalItem .Occurrence .Hours
173+
174+ interval_type_pairs .append ((interval_type , str (interval )))
175+
176+ return interval_type_pairs
116177
117178
118179class WeeklyInterval (object ):
@@ -155,7 +216,12 @@ def _interval_type_pairs(self):
155216class MonthlyInterval (object ):
156217 def __init__ (self , start_time , interval_value ):
157218 self .start_time = start_time
158- self .interval = str (interval_value )
219+
220+ # interval should be a tuple, if it is not, assign as a tuple with single value
221+ if isinstance (interval_value , tuple ):
222+ self .interval = interval_value
223+ else :
224+ self .interval = (interval_value ,)
159225
160226 def __repr__ (self ):
161227 return f"<{ self .__class__ .__name__ } start={ self .start_time } interval={ self .interval } >"
@@ -179,24 +245,24 @@ def interval(self):
179245 return self ._interval
180246
181247 @interval .setter
182- def interval (self , interval_value ):
183- error = "Invalid interval value for a monthly frequency: {}." .format (interval_value )
184-
248+ def interval (self , interval_values ):
185249 # This is weird because the value could be a str or an int
186250 # The only valid str is 'LastDay' so we check that first. If that's not it
187251 # try to convert it to an int, if that fails because it's an incorrect string
188252 # like 'badstring' we catch and re-raise. Otherwise we convert to int and check
189253 # that it's in range 1-31
254+ for interval_value in interval_values :
255+ error = "Invalid interval value for a monthly frequency: {}." .format (interval_value )
190256
191- if interval_value != "LastDay" :
192- try :
193- if not (1 <= int (interval_value ) <= 31 ):
194- raise ValueError (error )
195- except ValueError :
196- if interval_value != "LastDay" :
197- raise ValueError (error )
257+ if interval_value != "LastDay" :
258+ try :
259+ if not (1 <= int (interval_value ) <= 31 ):
260+ raise ValueError (error )
261+ except ValueError :
262+ if interval_value != "LastDay" :
263+ raise ValueError (error )
198264
199- self ._interval = str ( interval_value )
265+ self ._interval = interval_values
200266
201267 def _interval_type_pairs (self ):
202268 return [(IntervalItem .Occurrence .MonthDay , self .interval )]
0 commit comments