XLSX SheetJS解决日期43秒误差导致少一天的问题处理


问题描述

VUE项目使用XLSX来导入excel时,发现如果时日期类型,导入后,日期会少一天。具体情况如下:

XLSX SheetJS解决日期43秒误差导致少一天的问题处理

excel中设置的是:2025/05/16 

但是XLSX导入后,日期列就变成了

XLSX SheetJS解决日期43秒误差导致少一天的问题处理

发现少了 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中的值就是有问题的。

XLSX SheetJS解决日期43秒误差导致少一天的问题处理

通过查询得知,这个是常见问题:

根本原因:

  • 在 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));
	  }
	});
});

效果如下:

XLSX SheetJS解决日期43秒误差导致少一天的问题处理

 

方案特点

优点(加分项)

 

  1. 🔍 找到了根本原因
    它没有停留在“误差是 JS 精度问题”这种模糊层面,而是准确指出:

    • Excel 日期基准是 1899-12-30

    • JS DategetTimezoneOffset() 忽略了秒数

    • 中国标准时间在这个基准时间点上有 43 秒误差

  2. 🛠 提供了通用修复函数

    • importBugHotfixDiff 动态计算时区偏移

    • 不依赖硬编码(比如直接减 43 秒)

    • 适配任意时区,具备通用性

  3. 👨‍💻 实用性强

    • 不要求修改 SheetJS 源码或等待官方修复

    • 可直接在项目中集成,非侵入式

    • Vue / React / 任意前端框架都可以用

  4. 📚 可读性好
    封装良好,逻辑清晰,注释也不错。

 

 

版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
张国生
上一篇:XLSX SheetJS解决日期43秒误差导致少一天的问题处理
下一篇:开源网盘》》文件共享软件
评论列表

发表评论

评论内容
昵称:
关联文章

PVE硬盘对应SATA口查询

联系我们
联系电话:15090125178(微信同号)
电子邮箱:garson_zhang@163.com
站长微信二维码
微信二维码