最近实现了一个小功能---定时器。本来很简单的一个Timer就能解决的,偏偏要求传参两个时间过来如:[10,12],要做到10点开始,12点结束。这还不算完,还得给你咔咔咔,一下传好多个时间过来,做到分时段运行。来看看我使用的方式,如果你有更简单的方法记得在评论区告诉我。
基本解决思路
我打算使用定时器,来解决定时开关的问题。用数组来保存传入的值。然后我就碰到了几个问题。
1、如果传参过来是乱序的怎么办?
我首先实现了一个二维数组来保存开始结束时间,然后匹配到一个就退出来按照这个时间来开始运行,但是如果用户传入的值是乱序的怎么办。我就想到了排序,然后就是二维数组排序的问题。
网上找了各种二维数组排序的方式,各种不适用,从开始到放弃。然后我就想不是可以再获取到值后直接再比对一下所有的值,是否为当前符合要求的最小时间就可以了么。是的我也是这么做的,但是如果用户输入的是[10,12] [11,13] 或者[10,14] [11,12]。相信我,用元组数组就可以了,不要去用二维数组。就很好排序了,如下:
class Runtime:
def __init__(self,starttime,endtime):
self.starttime = starttime
self.endtime = endtime
def __repr__(self):
return repr((self.starttime,self.endtime))
def check_argu():
global lists
lists1 = sorted(lists, key=lambda runtime: int(runtime.endtime))
#结束时间不能小于开始时间
for m in lists:
if(m.endtime <= m.starttime):
print("endtime <= starttime,Please check the!")
return -1
#开始和结束时间排序,顺序要一致
if(lists != lists1):
print("Argument error ,Please check the!")
return -1
#上一次结束时间不能大于下一次开始时间
i = 0
while ((i+1)<len(lists)):
if(lists[i].endtime >= lists[i+1].starttime):
print("last endtime({0}) > next starttime({0}),Please check the!".format(lists[i].endtime,lists[i+1].starttime))
return -1
i += 1
return 0
def init(argu):
i = 0
global lists
for n in argu:
if(i == 0):
i += 1
continue
t = re.findall('\[([^]]+)\]', argu[i])
argument = ''.join(t)
#这个str1,str2能分别拿到split的值
str1, str2 = argument.split(',')
print('argument: %s or %s' %(str1, str2))
#元组数组
lists.append(Runtime(str1, str2))
i += 1
#排序
lists = sorted(lists, key=lambda runtime: int(runtime.starttime))
print (lists)
if(check_argu() != 0):
return -1
return 0
这样就完成了排序,检查时间的问题
2、定时器开关写法
相比上面,这个就好写多了。
def end():
global end_state
end_state = True
next_time = get_time()
if(next_time < 0):
return
end_state = False
timer = threading.Timer(next_time, main)
timer.start()
def main():
global timer_end_time
timer = threading.Timer(timer_end_time, end)
timer.start()
while True:
global end_state
if(end_state):
break
print("hahaha")
if __name__ == "__main__":
count = len(sys.argv)
if (count < 2):
logging.error('Please,Give one argument!')
else:
if(init(sys.argv) == 0):
next_time = get_time()
if(next_time >= 0):
#定时器,参数为(多少时间后执行,单位为秒,执行的方法)
timer = threading.Timer(next_time, main)
timer.start()
3、获取开始结束时间
def get_time():
# 获取现在时间
now_time = datetime.datetime.now()
next_start_hour = '0'
next_end_hour = '0'
global lists
for n in lists:
#print (n[1])
if(now_time.time().hour < int(n.starttime)):
#print (n[0],n[1])
if((int(n.starttime) < int(next_start_hour))|(next_start_hour == '0')):
next_start_hour = n.starttime
next_end_hour = n.endtime
if(next_start_hour == ''):
logging.error('Please,Give me the right time !')
return -1
print("next_start_hour",next_start_hour)
next_time = 0
if((int(next_end_hour) >= 24)):
# 获取明天时间
next_time = now_time + datetime.timedelta(days=+1)
next_end_hour = int(next_end_hour) - 24
else:
next_time = now_time
next_year = next_time.date().year
next_month = next_time.date().month
next_day = next_time.date().day
#获取下一次运行时间和结束的时间
next_start_time = datetime.datetime.strptime(str(next_year)+"-"+str(next_month)+"-"+str(next_day)+" {0}:00:00".format(next_start_hour), "%Y-%m-%d %H:%M:%S")
next_end_time = datetime.datetime.strptime(str(next_year)+"-"+str(next_month)+"-"+str(next_day)+" {0}:00:00".format(next_end_hour), "%Y-%m-%d %H:%M:%S")
# 获取距离下一次时间,单位为秒
global timer_end_time
timer_start_time = (next_start_time - now_time).total_seconds()
timer_end_time = (next_end_time - now_time).total_seconds()
print(timer_start_time)
return timer_start_time
结束语
源码飞机票:【源码】定时器在某个时间运行某个应用,并在某个时间结束
以上就是本次分享的定时器写法、多维数组排序的问题解法,以及时间戳获取方式。最后惯例给大家推介一下我们的技术工作号,欢迎大家来交流技术问题,谢谢!