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开发框架网发布内容,转载请附上原文出处连接
张国生
上一篇:Zookeeper 可视化管理工具
下一篇:开源网盘》》文件共享软件
评论列表

发表评论

评论内容
昵称:
关联文章

XLSX SheetJS解决日期43误差导致问题处理
解决new Thread().Start导致高并发CPU 100%问题
解决 Navicat 隔段时间就需要重新连接数据库问题
JSON.stringify 输出JSON字符串时对日期Date类型处理
C# 使用Newtonsoft对象转JSON字符串时候日期类型处理
利用Windbg分析Magicodes.IE次错误编写导致内存剧增
一劳永逸,解决.NET发布云服务器时区问题
消息发送时问题
JavaScript JS高精度计算方法与库推荐,数值运算误差
模仿写了一个摸鱼应用解决原作者问题
解决Nancy参数绑定“bug”开始发布自己第一个nuget包(上篇)
Python读取excel xlrd读取xlsx报错:Excel xlsx file; not supported
bat批处理中执行gulp界面闪而过,执行完后cmd窗口就会关闭解决办法
解决VUE发布后因为浏览器缓存造成页面没更新问题
解决:旧项目升级新版Unity2021导致Visual Studio无法使用
dotnet 通过 DockerfileContext 解决项目放在里层文件夹导致 VisualStudio 构建失败
CMD运行命令程序自动暂停问题解决
解决WebClient或HttpWebRequest首次连接缓慢问题
C# Newtonsoft日期格式化处理
SQLite Database 多线程访问需要注意问题

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