def analyze(self, timestamp, cron_str): """ 处理cron表达式 :param cron_str: :return: """ x = time.localtime(timestamp) second = x.tm_sec minute = x.tm_min hour = x.tm_hour day = x.tm_mday month = x.tm_mon year = x.tm_year cron_list = cron_str.split(' ') second_str = cron_list[0] minute_str = cron_list[1] hour_str = cron_list[2] day_str = cron_list[3] month_str = cron_list[4] right_second, second_index, next_second_index, second_list, second_carry = self.process_base(second_str, 0, 59, second, 0) right_minute, minute_index, next_minute_index, minute_list, minute_cary = self.process_base(minute_str, 0, 59, minute, second_carry) right_hour, hour_index, next_hour_index, hour_list, hour_carry = self.process_base(hour_str, 0, 23, hour, minute_cary) right_day, day_index, next_day_index, day_list, day_cary = self.process_base(day_str, 1, 31, day, hour_carry) right_month, month_index, next_month_index, month_list, month_carry = self.process_base(month_str, 1, 12, month, day_cary) # left_days = (datetime.date(year, right_month, right_day) - datetime.date(year, month, day)).days # left_hour = right_hour - hour # left_minute = right_minute - minute # left_second = right_second - second # # 从小时到秒,挨个判断 # if left_hour < 0: # # 处理小时 # left_hour += 24 # elif left_hour == 0 and left_minute < 0: # left_minute += 60000 # elif left_hour == 0 and left_minute == 0 and left_second < 0: # if minute_str == '*': # left_second += 60 # elif hour_str == '*': # left_minute += 60 # elif day_str == '*': # left_hour += 24 # # left_timestamp = (((left_days * 24 + left_hour) * 60) + left_minute) * 60 + left_second if month_carry: right_month += month_carry date = ('{}-%s-%s %s:%s:%s' % tuple([('00'+str(i))[-2:] for i in (month, day, hour, minute, second)])).format(year) right_date = ('{}-%s-%s %s:%s:%s' % tuple([('00'+str(i))[-2:] for i in (right_month, right_day, right_hour, right_minute, right_second)])).\ format(year) left_timestamp = DateUtils.str_to_time(right_date) - DateUtils.str_to_time(date) return left_timestamp
async def cal_next_start_time(job, is_normal=True): """ 计算下一次定时任务发生的时间 :param job: :param is_normal :return: """ # 无限循环执行, 必定带正则表达式,否则直接报错 # 解析正则表达式, 计算出下一次需要执行的时间点 if not is_normal: current_time = int(DateUtils.timestamps_now()) else: current_time = DateUtils.str_to_time(job['start_time']) left_time = cron_utils.analyze(current_time + 1, job['cron']) start_time = DateUtils.format_time(current_time + left_time) # 计算距离start_time最近的RUN_TIME秒 current_date = start_time[:16] + ':00' current_count = 1 while current_date < start_time: # 避免死循环 if current_count >= 1000: break current_count += 1 current_date = DateUtils.add_second(current_date, seconds=run_time) start_time = current_date job['start_time'] = start_time cache_key = ServiceBase.schedule.JOB_KEY + job['start_time'].replace( ' ', '').replace('-', '').replace(':', '') now_date = DateUtils.time_now() # 如果下一次的执行时间小于当前时间,则跳至下一个执行的时间节点 if job['start_time'] < now_date: logger.info('任务下一次执行时间小于当前时间') current_date = now_date[:16] + ':00' while current_date < now_date: current_date = DateUtils.add_second(current_date, seconds=2 * run_time) job['start_time'] = current_date cache_key = ServiceBase.schedule.JOB_KEY + job['start_time'].replace( ' ', '').replace('-', '').replace(':', '') model = importlib.import_module('task.schedule.model') model = model.Model() await model.update_job(job) await redis.sadd(cache_key, json.dumps(job, cls=CJsonEncoder)) length = await redis.scard(cache_key) await redis.hset(ServiceBase.schedule.SCHEDULE_KEY, cache_key, length)
def analyze(self, timestamp, cron_str): """ 处理cron表达式 :param cron_str: :return: """ x = time.localtime(timestamp) second = x.tm_sec minute = x.tm_min hour = x.tm_hour day = x.tm_mday month = x.tm_mon year = x.tm_year month_max_days = calendar.monthrange(year, month)[1] cron_list = cron_str.split(' ') second_str = cron_list[0] minute_str = cron_list[1] hour_str = cron_list[2] day_str = cron_list[3] month_str = cron_list[4] right_second, second_index, next_second_index, second_list, second_carry = self.process_base( second_str, 0, 59, second, 0) right_minute, minute_index, next_minute_index, minute_list, minute_cary = self.process_base( minute_str, 0, 59, minute, second_carry) right_hour, hour_index, next_hour_index, hour_list, hour_carry = self.process_base( hour_str, 0, 23, hour, minute_cary) right_day, day_index, next_day_index, day_list, day_cary = self.process_base( day_str, 1, month_max_days, day, hour_carry) right_month, month_index, next_month_index, month_list, month_carry = self.process_base( month_str, 1, 12, month, day_cary) # left_days = (datetime.date(year, right_month, right_day) - datetime.date(year, month, day)).days # left_hour = right_hour - hour # left_minute = right_minute - minute # left_second = right_second - second # # 从小时到秒,挨个判断 # if left_hour < 0: # # 处理小时 # left_hour += 24 # elif left_hour == 0 and left_minute < 0: # left_minute += 60000 # elif left_hour == 0 and left_minute == 0 and left_second < 0: # if minute_str == '*': # left_second += 60 # elif hour_str == '*': # left_minute += 60 # elif day_str == '*': # left_hour += 24 # # left_timestamp = (((left_days * 24 + left_hour) * 60) + left_minute) * 60 + left_second if month_carry: right_month += month_carry date = ( '{}-%s-%s %s:%s:%s' % tuple([('00' + str(i))[-2:] for i in (month, day, hour, minute, second)])).format(year) right_date = ('{}-%s-%s %s:%s:%s' % tuple([('00'+str(i))[-2:] for i in (right_month, right_day, right_hour, right_minute, right_second)])).\ format(year) left_timestamp = DateUtils.str_to_time( right_date) - DateUtils.str_to_time(date) return left_timestamp