这类问题我又碰上了一次。openpyxl 3.1 读 xlsx,日期列读出来是 45000 这类整数,直接入库全变成 1970 年,Excel 里打开显示的是正常日期。
第一反应是「Excel 的 1900 闰年基准与 Unix 时间不同」,验证下来不成立。
排查方向其实有限,先把可能性排一排。单元格是数字格式,只是显示层做了日期格式化;number_format 没判断就直接取值;pandas 读取时没指定 parse_dates。
先看单元格的格式字符串
python -c "import openpyxl;wb=openpyxl.load_workbook('data.xlsx');c=wb.active['C2'];print(c.value,c.number_format)"
然后用 from_excel 转成真正的日期
python -c "from openpyxl.utils.datetime import from_excel;print(from_excel(45000))"
随后改 pandas 读取时显式解析日期列
python -c "import pandas as pd;d=pd.read_excel('data.xlsx',parse_dates=['日期']);print(d.dtypes)"
入库前断言列类型是 datetime
python -c "import pandas as pd;d=pd.read_excel('data.xlsx');print(pd.api.types.is_datetime64_any_dtype(d['日期']))"
隔了一天再看,现象没变,说明不是偶发。
那几天正好在做别的变更,先把时间线对齐才敢动手。
排查用的命令都是临时敲的,没有写成脚本,事后才整理。
怎么算真的好了,看的是同一批现象。日期列读出的是 datetime 对象,入库后与 Excel 显示一致,45000 对应的 2023-03-15 没有偏差。
Excel 里的日期本质是数字加格式,读表时要同时看 value 和 number_format,只看值就会把日期当整数。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。
