XLSX SheetJS解决日期43秒误差导致少一天的问题处理
问题描述
VUE项目使用XLSX来导入excel时,发现如果时日期类型,导入后,日期会少一天。具体情况如下:
excel中设置的是:2025/05/16
但是XLSX导入后,日期列就变成了
发现少了 43秒,从而造成提前了一天
excel读取代码如下:
JavaScript 全选
var workbook = XLSX.read(data, {
type: 'array',
// cellText:false,
cellDates: true, // 如果设置为true,将天数的时间戳转换为时间格式
})
const worksheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[worksheetName];
var jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 'A' });
原因分析
通过断点追踪,发现worksheet中的值就是有问题的。
通过查询得知,这个是常见问题:
根本原因:
- 在 Excel 中,日期是被存储为自 1899 年 12 月 30 日以来的天数,以整数形式存储。
- 中国时区在 1899 年的时差偏移量是 +8:05:43(附:时区变化)
- SheetJS 使用了 getTimezoneOffset 来解决误差,但是 getTimezoneOffset 以整数形式返回分钟部分,忽略了秒的部分,所以造成了 43 秒的误差。
参考:SheetJS.xlsx 解析日期类型丢失 43 秒的问题在使用 `SheetJS.xlsx` 库调用 `xlsx.re - 掘金
解决方案
手动处理一下日期,给日期加上相差的秒误差值
添加方法,计算当前时区与1899年12月30日时区之间的时间差(以毫秒为单位)
JavaScript 全选
// 返回当前时区与该日期所在时区之间的时间差(以毫秒为单位)
const getTimezoneOffsetMS = (date: Date) => {
const time = date.getTime();
const utcTime = Date.UTC(
date.getFullYear(),
date.getMonth(),
date.getDate(),
date.getHours(),
date.getMinutes(),
date.getSeconds(),
date.getMilliseconds(),
);
return time - utcTime;
}
// 计算当前时区与1899年12月30日时区之间的时间差(以毫秒为单位)
const importBugHotfixDiff = (function () {
const baseDate = new Date(1899, 11, 30, 0, 0, 0);
const dnThreshAsIs = (new Date().getTimezoneOffset() - baseDate.getTimezoneOffset()) * 60000;
const dnThreshToBe = getTimezoneOffsetMS(new Date()) - getTimezoneOffsetMS(baseDate);
return dnThreshAsIs - dnThreshToBe;
}());
EXCEL文件读取后,用Foreach循环来处理日期精度问题
JavaScript 全选
var workbook = XLSX.read(data, {
type: 'array',
// cellText:false,
cellDates: true, // 如果设置为true,将天数的时间戳转换为时间格式
})
const worksheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[worksheetName];
var jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 'A' });
// 修复日期精度损失问题
jsonData.forEach(row => {
Object.keys(row).forEach(key => {
if (row[key] instanceof Date) {
// 修复日期的精度损失(需要注意传入的 Date 对象必须是已经转换为当前时区 Date 对象)
row[key] = (new Date(row[key].getTime() - importBugHotfixDiff));
}
});
});
效果如下:
方案特点
优点(加分项)
🔍 找到了根本原因
它没有停留在“误差是 JS 精度问题”这种模糊层面,而是准确指出:Excel 日期基准是 1899-12-30
JS
Date
的getTimezoneOffset()
忽略了秒数中国标准时间在这个基准时间点上有 43 秒误差
🛠 提供了通用修复函数
importBugHotfixDiff
动态计算时区偏移不依赖硬编码(比如直接减 43 秒)
适配任意时区,具备通用性
👨💻 实用性强
不要求修改 SheetJS 源码或等待官方修复
可直接在项目中集成,非侵入式
Vue / React / 任意前端框架都可以用
📚 可读性好
封装良好,逻辑清晰,注释也不错。
版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
post 张国生