You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于datetime模块实现Python脚本每日定时执行的问题求助

问题分析与解决方案

原代码的核心问题

  1. 第一版代码中,balance = deposit + percentage会在每次循环时重置余额,覆盖之前的累加值,导致无法正确累计收益。
  2. 第二版代码缺少等待到目标执行时间的逻辑,只是简单判断当前小时是否为2点,若启动时不是该时间则直接跳过,无法实现每日定时执行;同时循环逻辑不完整,会出现一次性执行的问题。
  3. 持续循环检查的方式会持续占用系统资源,功耗较高。

更优实现方案

方案一:利用系统定时任务(最省功耗)

这种方式不需要脚本持续运行,而是让系统每天定时触发脚本执行一次,通过文件持久化保存余额状态,是最节省资源的方案。

实现代码

import datetime
import json
import os

# 配置参数
PERCENTAGE = 5
DEPOSIT = 0
EXPIRING_DAYS = 7  # 连续执行7天
STATE_FILE = "balance_state.json"

def load_state():
    # 读取已保存的余额和日期状态
    if os.path.exists(STATE_FILE):
        with open(STATE_FILE, "r") as f:
            return json.load(f)
    # 首次执行初始化状态
    start_date = datetime.date.today()
    expiring_date = start_date + datetime.timedelta(days=EXPIRING_DAYS)
    return {
        "balance": DEPOSIT + PERCENTAGE,
        "current_date": start_date.isoformat(),
        "expiring_date": expiring_date.isoformat()
    }

def save_state(state):
    # 保存最新状态到文件
    with open(STATE_FILE, "w") as f:
        json.dump(state, f, indent=2)

def main():
    state = load_state()
    current_date = datetime.date.fromisoformat(state["current_date"])
    expiring_date = datetime.date.fromisoformat(state["expiring_date"])
    
    # 判断是否已到期
    if current_date >= expiring_date:
        print("已达到期日期,停止执行")
        os.remove(STATE_FILE)  # 清理状态文件
        return
    
    # 执行余额累加
    state["balance"] += PERCENTAGE
    # 更新下一次执行的日期
    next_date = current_date + datetime.timedelta(days=1)
    state["current_date"] = next_date.isoformat()
    
    save_state(state)
    print(f"今日执行完成,当前余额: {state['balance']},下次执行日期: {next_date}")

if __name__ == "__main__":
    main()

系统定时任务配置

  • Linux/macOS:执行crontab -e,添加以下内容(替换脚本路径):
    0 2 * * * /usr/bin/python3 /path/to/your/script.py
    
    表示每天凌晨2点自动执行脚本。
  • Windows:打开「任务计划程序」,创建基本任务:
    1. 触发时间设置为「每天」,时间选凌晨2点;
    2. 操作选择「启动程序」,程序选Python的exe路径,添加参数为你的脚本路径。

方案二:脚本内部休眠到目标时间(无需系统定时)

如果不想依赖系统定时任务,可以让脚本计算距离下次执行的时间,直接休眠到目标点,期间CPU占用极低,同样节省功耗。

实现代码

import datetime
import time

PERCENTAGE = 5
DEPOSIT = 0
EXPIRING_DAYS = 7
TARGET_HOUR = 2  # 每日凌晨2点执行

def calculate_next_run_time():
    now = datetime.datetime.now()
    # 计算今日目标执行时间
    target_today = now.replace(hour=TARGET_HOUR, minute=0, second=0, microsecond=0)
    # 如果当前时间已过今日目标点,就推到明天
    if now >= target_today:
        next_run = target_today + datetime.timedelta(days=1)
    else:
        next_run = target_today
    return next_run

def main():
    balance = DEPOSIT + PERCENTAGE  # 首次执行初始余额
    start_date = datetime.date.today()
    expiring_date = start_date + datetime.timedelta(days=EXPIRING_DAYS)
    
    while datetime.date.today() < expiring_date:
        # 计算需要休眠的时长
        next_run = calculate_next_run_time()
        sleep_seconds = (next_run - datetime.datetime.now()).total_seconds()
        print(f"等待至{next_run.strftime('%Y-%m-%d %H:%M')}执行,将休眠{sleep_seconds/3600:.2f}小时")
        time.sleep(sleep_seconds)
        
        # 执行余额累加
        balance += PERCENTAGE
        current_date = datetime.date.today()
        print(f"[{current_date.strftime('%Y-%m-%d')}] 执行完成,当前余额: {balance}")
    
    print("已达到期日期,程序结束")

if __name__ == "__main__":
    main()

内容的提问来源于stack exchange,提问作者Buchii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 01:11:08