@@ -20,11 +20,49 @@ class MyCronTrigger(CronTrigger):
2020 @classmethod
2121 def from_crontab (cls , expr , timezone = None ):
2222 values = expr .split ()
23- if len (values ) != 7 :
24- raise ValueError ('Wrong number of fields; got {}, expected 7' .format (len (values )))
23+ if len (values ) != 6 and len ( values ) != 7 :
24+ raise ValueError ('Wrong number of fields; got {}, expected 6 or 7' .format (len (values )))
2525
26- return cls (second = values [0 ], minute = values [1 ], hour = values [2 ], day = values [3 ], month = values [4 ],
27- day_of_week = values [5 ], year = values [6 ], timezone = timezone )
26+ second = values [0 ]
27+ minute = values [1 ]
28+ hour = values [2 ]
29+ if '?' in values [3 ]:
30+ day = None
31+ elif 'L' in values [5 ]:
32+ day = f"last { values [5 ].replace ('L' , '' )} "
33+ elif 'W' in values [3 ]:
34+ day = cls .__find_recent_workday (int (values [3 ].split ('W' )[0 ]))
35+ else :
36+ day = values [3 ].replace ('L' , 'last' )
37+ month = values [4 ]
38+ if '?' in values [5 ] or 'L' in values [5 ]:
39+ week = None
40+ elif '#' in values [5 ]:
41+ week = int (values [5 ].split ('#' )[1 ])
42+ else :
43+ week = values [5 ]
44+ if '#' in values [5 ]:
45+ day_of_week = int (values [5 ].split ('#' )[0 ]) - 1
46+ else :
47+ day_of_week = None
48+ year = values [6 ] if len (values ) == 7 else None
49+ return cls (second = second , minute = minute , hour = hour , day = day , month = month , week = week ,
50+ day_of_week = day_of_week , year = year , timezone = timezone )
51+
52+ @classmethod
53+ def __find_recent_workday (cls , day ):
54+ now = datetime .now ()
55+ date = datetime (now .year , now .month , day )
56+ if date .weekday () < 5 :
57+ return date .day
58+ else :
59+ diff = 1
60+ while True :
61+ previous_day = date - timedelta (days = diff )
62+ if previous_day .weekday () < 5 :
63+ return previous_day .day
64+ else :
65+ diff += 1
2866
2967
3068job_stores = {
0 commit comments