
本文介绍如何从分号分隔的 .txt 文件中提取任务截止日期(第4列),将其解析为 datetime 对象,并与系统当前日期比较,准确统计逾期任务数量。重点解决字符串解析、循环作用域、日期格式转换及逻辑计数等初学者常见问题。
本文介绍如何从分号分隔的 `.txt` 文件中提取任务截止日期(第4列),将其解析为 `datetime` 对象,并与系统当前日期比较,准确统计逾期任务数量。重点解决字符串解析、循环作用域、日期格式转换及逻辑计数等初学者常见问题。
在任务管理系统中,常需基于文本文件(如 tasks.txt)动态分析任务状态。典型格式为:用户;任务标题;描述;截止日期;创建日期;完成状态,其中截止日期以 YYYY-MM-DD 字符串形式存储(如 "2024-05-20")。要判断任务是否逾期,不能直接用字符串比较,必须将其转换为 datetime 对象后与 datetime.today() 进行数值化比对。
以下是一个完整、健壮的实现方案:
import datetime
# 初始化统计字典
stat_dict_task_overview = {
"Tasks": 0,
"Completed": 0,
"Uncompleted": 0,
"Overdue": 0,
"Percentage Incomplete": 0,
"Percentage Overdue": 0
}
# 安全读取文件(推荐使用 with 语句,此处为兼容原逻辑保留 open,但建议升级)
try:
with open("tasks.txt", "r", encoding="utf-8") as tasks:
for line in tasks:
# 去除首尾空白(尤其关键:消除换行符 \n)→ 避免 strptime 解析失败
stripped_line = line.strip()
if not stripped_line: # 跳过空行
continue
split_by_semi = stripped_line.split(";")
# 确保行数据完整(至少6个字段)
if len(split_by_semi) < 6:
print(f"警告:跳过格式异常行 → {line.rstrip()}")
continue
user, title, desc, due_date_str, date_added, completed = split_by_semi
# ✅ 步骤1:累加总任务数(每行一个任务)
stat_dict_task_overview["Tasks"] += 1
# ✅ 步骤2:按完成状态分类计数
if completed.strip() == "Yes":
stat_dict_task_overview["Completed"] += 1
else:
stat_dict_task_overview["Uncompleted"] += 1
# ✅ 步骤3:解析截止日期并比对当前日期
try:
due_date_obj = datetime.datetime.strptime(due_date_str.strip(), "%Y-%m-%d")
today = datetime.datetime.today()
# 注意:逾期 = 截止日期 < 今天(不含今日到期任务)
if due_date_obj.date() < today.date():
stat_dict_task_overview["Overdue"] += 1
except ValueError as e:
print(f"日期解析错误('{due_date_str}'):{e} → 跳过该任务")
except FileNotFoundError:
print("错误:未找到 tasks.txt 文件,请检查路径。")
except Exception as e:
print(f"读取文件时发生未知错误:{e}")
# ✅ 计算百分比(可选,增强实用性)
if stat_dict_task_overview["Tasks"] > 0:
stat_dict_task_overview["Percentage Incomplete"] = round(
(stat_dict_task_overview["Uncompleted"] / stat_dict_task_overview["Tasks"]) * 100, 2
)
stat_dict_task_overview["Percentage Overdue"] = round(
(stat_dict_task_overview["Overdue"] / stat_dict_task_overview["Tasks"]) * 100, 2
)
# 输出结果
print(stat_dict_task_overview)关键要点说明:
- strip() 不可省略:.split(";") 前必须调用 line.strip(),否则末尾 \n 会导致 due_date_str 实际为 "2024-05-20\n",strptime 将抛出 ValueError。
- 逻辑必须在循环内:所有 += 1 操作(包括 Tasks、Completed、Overdue)都需置于 for 循环体内,否则仅处理最后一行。
- 日期比对要转为 date():datetime.today() 返回带时分秒的 datetime 对象,而截止日期无时间信息;使用 .date() 提取日期部分再比较,语义更清晰且避免时区/时间精度干扰。
- 异常防护优先:添加 try/except 捕获 ValueError(格式错误)和 FileNotFoundError(文件缺失),提升程序鲁棒性。
- 字段校验防崩溃:检查 split_by_semi 长度,避免索引越界(如空行或格式错乱行)。
运行后,示例数据中仅第二行 2024-05-20(未来日期)不逾期,其余三行截止日早于今日(假设当前为 2024-03-05 后),将被计入 "Overdue": 3。此方法简洁、可维护,适用于各类基于文本的任务状态分析场景。
立即学习“Python免费学习笔记(深入)”;



















