我的知识记录

Python批量修改文件创建时间和修改时间教程

用Python批量设置文件的创建时间、修改时间、访问时间,支持从文件名提取日期、统一设为指定时间,整理归档文件时间戳利器。

Python批量修改文件创建时间修改时间教程

场景痛点

一批文件从压缩包里解压出来,所有文件的时间戳全变成了解压那一刻,完全看不出原始创建时间。或者想把一批归档文件的时间统一调整成某个日期,手动右键属性改一个文件要十几秒,几百个文件改一天。用Python批量设置时间戳,几秒钟搞定,还能从文件名里自动提取日期当新时间。

用到的库

pip install openpyxl

核心用标准库 ospathlibdatetime,日志用 openpyxl

完整代码

import os
import re
from pathlib import Path
from datetime import datetime
from openpyxl import Workbook


def set_file_time(file_path: Path, new_mtime: datetime,
new_ctime: datetime = None):
"""
设置文件的修改时间(和创建时间)。
new_mtime: 新的修改时间
new_ctime: 新的创建时间,None 则和修改时间保持一致
"""
if new_ctime is None:
new_ctime = new_mtime

# os.utime 设置访问时间和修改时间
os.utime(file_path, (new_mtime.timestamp(), new_mtime.timestamp()))

# Windows 下单独设置创建时间(标准库没有跨平台API,用ctypes调系统API)
if os.name == "nt":
try:
import win32_setctime
win32_setctime.setctime(str(file_path), new_ctime.timestamp())
except ImportError:
print("提示:未安装 win32-setctime,创建时间未修改(仅改了修改时间)")


def batch_set_time(folder: str, target_time: datetime,
extensions: list = None):
"""把目录下所有文件的时间统一改成 target_time。"""
root = Path(folder)
exts = {e.lower() for e in extensions} if extensions else None
done = []

for p in root.iterdir():
if not p.is_file():
continue
if exts and p.suffix.lower() not in exts:
continue
set_file_time(p, target_time)
done.append(str(p))
print(f"已修改:{p.name} -> {target_time.strftime('%Y-%m-%d %H:%M:%S')}")

return done


def parse_date_from_name(filename: str):
"""从文件名里提取日期,支持 2025-01-15、20250115、2025_01_15 等格式。"""
# 匹配 8 位数字日期:20250115 或 2025-01-15 或 2025_01_15
m = re.search(r"(20\d{2})[-_]?(\d{2})[-_]?(\d{2})", filename)
if not m:
return None
try:
return datetime(int(m.group(1)), int(m.group(2)), int(m.group(3)))
except ValueError:
return None


def batch_set_time_from_name(folder: str):
"""文件名里有日期的,把文件时间改成那个日期。"""
root = Path(folder)
done = []
skipped = []

for p in root.iterdir():
if not p.is_file():
continue
dt = parse_date_from_name(p.stem)
if dt is None:
skipped.append((p.name, "文件名中未找到日期"))
continue
set_file_time(p, dt)
done.append((p.name, dt.strftime("%Y-%m-%d")))
print(f"{p.name} -> {dt.strftime('%Y-%m-%d')}")

return done, skipped


def export_log(done: list, out_path: str):
wb = Workbook()
ws = wb.active
ws.title = "时间修改记录"
ws.append(["序号", "文件名", "新时间"])
for idx, (name, dt) in enumerate(done, 1):
ws.append([idx, name, dt])
ws.column_dimensions['A'].width = 8
ws.column_dimensions['B'].width = 50
ws.column_dimensions['C'].width = 22
wb.save(out_path)


if __name__ == "__main__":
FOLDER = r"D:\工作资料\归档合同"

# 方式一:统一设置成某个日期
# TARGET = datetime(2025, 1, 15, 10, 0, 0)
# done = batch_set_time(FOLDER, TARGET)

# 方式二:从文件名提取日期当新时间
done, skipped = batch_set_time_from_name(FOLDER)
print(f"\n成功 {len(done)} 个,跳过 {len(skipped)} 个")
export_log(done, r"D:\工作资料\时间修改记录.xlsx")

代码讲解

os.utime(路径, (访问时间戳, 修改时间戳)) 是标准库修改时间的入口,一次能改访问时间和修改时间两个。Windows下的创建时间比较特殊,os.utime 管不到,需要 win32-setctime 这个第三方库配合(pip install win32-setctime)。parse_date_from_name 用正则从文件名里抓日期:20\d{2} 匹配20开头的年份,[-_]? 兼容横杠、下划线、无分隔符三种写法。batch_set_time_from_name 适合"文件名本身就带日期"的归档场景,自动把文件时间对齐到文件名日期。

运行结果

控制台逐文件打印新时间,最后生成 时间修改记录.xlsx。右键任意文件看属性,创建时间和修改时间都变成了脚本设置的值。资源管理器按修改时间排序,顺序和文件名日期完全一致。

注意事项

  • os.utime 标准库只能改访问时间和修改时间,Windows创建时间需要额外装 win32-setctime
  • Linux/macOS没有严格意义上的"创建时间",st_ctime 是元数据变更时间,不要强改。
  • 网盘同步文件夹改完时间会触发重新同步,注意流量。
  • 从文件名解析日期时,文件名里有别的8位数字(比如金额、订单号)可能误匹配,先小批量测试。

Python批量修改文件创建时间和修改时间教程

标签:

更新时间:2026-09-14 21:31:05

上一篇:Python 批量按文件类型分类整理:递归扫描全盘资料

下一篇:Python批量修改文件后缀扩展名:一键重命名所有文件类型