convert-excel-to-json转换Excel日期多16秒 存入MongoDB ISODate异常
异常根因
这个16秒偏差和MongoDB的存储逻辑没有任何关系,问题完全出在convert-excel-to-json的默认日期解析环节:
- 你当前写的转换配置没有对
DATE列做任何格式处理规则,包会自动识别Excel单元格类型做隐式类型转换。 - Excel本身存日期不是存标准时间字符串,是存一个浮点数,代表从1900-01-00开始累计的天数,小数部分对应时分秒,解析库需要把这个浮点数反向换算成JS的Date对象。另外Excel本身有个历史遗留bug:错误把1900年识别为闰年,多算了不存在的1900年2月29日,所有正经Excel解析库都会专门做减1天的偏移修正。
- 你碰到的固定16秒偏差,是老版本
convert-excel-to-json依赖的底层xlsx解析库的已知bug:当单元格里的日期带非UTC时区偏移时,库内部做闰年偏移修正和时区换算的过程中出现了浮点数精度截断,最终算出来的时间就会固定多出来16秒。
修复方法
- 最省事的方案:直接把
convert-excel-to-json升级到最新版,这个换算精度问题在新版本里已经修复了。 - 最稳妥的方案:在转换配置里给DATE列加自定义转换逻辑,跳过库自带的默认日期解析,自己用日期处理库按原始格式解析时间,参考代码如下:
const excelToJson = require('convert-excel-to-json'); const dayjs = require('dayjs'); const utc = require('dayjs/plugin/utc'); const timezone = require('dayjs/plugin/timezone'); dayjs.extend(utc); dayjs.extend(timezone); const convertExcel = async (path) => { const result = excelToJson({ sourceFile: path, sheets: [ { name: "Sheet1", header: { rows: 1, }, columnToKey: { A: "DATE", }, customFields: { DATE: (rawValue) => { // 按Excel内实际的日期格式、对应时区解析后转成标准JS Date对象 return dayjs.tz(rawValue, "YYYY-MM-DD HH:mm:ss", "America/New_York").toDate(); } } }, ], }); Collection.insertMany(result.Sheet1); };
- 临时凑活的方案:拿到转换结果后遍历数据,手动把DATE字段的秒、毫秒数置为0,直接抹掉16秒的偏差,这种硬编码方式容错性差,不推荐长期用。
内容的提问来源于stack exchange,提问作者Legion
相关产品推荐
相关产品推荐

