Python datetime时间判断异常:程序持续运行时倒计时显示错误
问题排查与修复
问题根源
你的代码里target_time仅在程序启动时计算一次,当时间到达设定的目标点后,循环中没有更新target_time为下一个目标时间。当当前时间超过已设定的target_time时,datetime.datetime.combine(datetime.date.today(), target_time)会生成一个早于当前时间的datetime对象,计算出的time_diff为负数。而timedelta.seconds返回的是总秒数对86400(一天的秒数)取模的结果,负数会转化为接近24小时的正数,最终导致错误的倒计时显示。
修复方案
把目标时间的判断逻辑移到循环内部,每次循环都重新确定下一个目标时间;同时处理跨天的时间计算(比如午夜00:00的目标需要结合次日日期)。
修复后的完整代码:
import pyautogui from tkinter import * import win32gui import datetime from time import sleep # 获取屏幕和任务栏尺寸 taskbar_hwnd = win32gui.FindWindow("Shell_TrayWnd", None) taskbar_rect = win32gui.GetWindowRect(taskbar_hwnd) task_height = taskbar_rect[1] width, _ = pyautogui.size() # Tkinter GUI初始化 root = Tk() root.geometry(f"{width}x20+0+{task_height - 20}") root.overrideredirect(True) root.attributes('-topmost', True) lb1 = Label(root, text='Loading...', bg='blue', fg='white', font=('Montserrat semibold', 8)) lb1.place(x=0, relwidth=1) root.update() # 定义目标时间 first_morning_target = datetime.time(10, 0) second_morning_target = datetime.time(12, 0) first_afternoon_target = datetime.time(16, 0) second_afternoon_target = datetime.time(18, 0) first_night_target = datetime.time(20, 0) second_night_target = datetime.time(0, 0) while True: current_dt = datetime.datetime.now() current_time = current_dt.time() # 重新计算当前的下一个目标时间 if current_time < first_morning_target: target_time = first_morning_target target_date = datetime.date.today() elif first_morning_target <= current_time < second_morning_target: target_time = second_morning_target target_date = datetime.date.today() elif second_morning_target <= current_time < first_afternoon_target: target_time = first_afternoon_target target_date = datetime.date.today() elif first_afternoon_target <= current_time < second_afternoon_target: target_time = second_afternoon_target target_date = datetime.date.today() elif second_afternoon_target <= current_time < first_night_target: target_time = first_night_target target_date = datetime.date.today() elif first_night_target <= current_time < second_night_target: target_time = second_night_target target_date = datetime.date.today() + datetime.timedelta(days=1) # 跨天,用次日日期 else: target_time = first_morning_target target_date = datetime.date.today() # 计算时间差 target_dt = datetime.datetime.combine(target_date, target_time) time_diff = target_dt - current_dt # 计算剩余时分秒 total_seconds = time_diff.total_seconds() remaining_hours = int(total_seconds // 3600) remaining_minutes = int((total_seconds % 3600) // 60) remaining_seconds = int(total_seconds % 60) # 更新标签文本 if (first_morning_target <= current_time < second_morning_target) or \ (first_afternoon_target <= current_time < second_afternoon_target) or \ (first_night_target <= current_time < second_night_target): text = f"{current_dt.strftime('%I:%M %p')} Bot awake, {remaining_hours} hour(s), {remaining_minutes} minute(s) e {remaining_seconds} second(s) for the bot to finish" lb1.config(text=text, bg='#2dff26') else: text = f"{current_dt.strftime('%I:%M %p')} Bot resting, {remaining_hours} hour(s), {remaining_minutes} minute(s) e {remaining_seconds} second(s) for the bot to start" lb1.config(text=text, bg='blue') root.update() sleep(1)
关键修复点
- 将目标时间判断逻辑移入
while循环,每次循环都重新确定下一个目标时间,确保时间到达目标点后能自动切换到下一个节点。 - 处理跨天场景:当目标时间为午夜00:00时,使用次日日期来计算时间差,避免出现负数时间差导致的错误倒计时。
- 使用
total_seconds()计算总剩余秒数,替代原来的time_diff.seconds,确保时间差计算准确(包括跨天的情况)。
内容的提问来源于stack exchange,提问作者BOB CÓMUNISTA
相关产品推荐
相关产品推荐

