JS怎么获取秒级时间戳

作者:键盘侠

时间:2026-11-03

浏览:585

JavaScript原生获取的时间戳均为13位毫秒级。本文系统讲解如何使用Math.floor(Date.now() / 1000)获取标准10位秒级时间戳,对比多种取整方案的优缺点,指出位运算可能引发的2038年溢出陷阱,并提供常见联调问题的排查方案。

文章目录
JavaScript 实用指南
主题:时间戳处理 环境:浏览器 / Node.js 标准单位:Unix 秒级 (10位)
JS怎么获取秒级时间戳
图 0:JavaScript 秒级时间戳标准换算概要

在 JavaScript 中获取秒级时间戳的最稳妥做法是:Math.floor(Date.now() / 1000)。JavaScript 原生时间 API(包括 Date.now() 和 new Date().getTime())默认返回的是 13 位的毫秒级时间戳,通过除以 1000 并向下取整,即可将其规整为标准 Unix 的 10 位秒级时间戳。

一、为什么 JavaScript 默认没有“秒级时间戳”?

Unix 时间戳最初被定义为从 UTC 1970 年 1 月 1 日 00:00:00 起所流逝的秒数,总长度通常为 10 位(如 1730421045)。而 JavaScript 诞生的 1995 年前后,Web 动画和高精度交互要求运行时具有毫秒级计时能力,因此 ECMAScript 标准在制定 Date 对象时,底层存储的时间数值均以毫秒(Milliseconds)为基准,长度为 13 位(如 1730421045123)。

在与后端系统(如 Linux 运维服务、Python 的 time.time()、PHP 的 time()、Go 的 time.Now().Unix())或各类第三方开放平台 API 进行数据对接时,接口通常强制要求传入 10 位的秒级整型数值。如果直接把 JavaScript 的 13 位毫秒数值传给后端,会导致解析出的年份变成 5 万多年后的远古未来,从而引发业务逻辑崩溃。

JS怎么获取秒级时间戳
图 1:13 位毫秒数值向 10 位标准 Unix 秒级时间戳的数据截断与转换过程

二、获取当前秒级时间戳的标准操作

获取当前时刻的秒级时间戳,核心在于两步:读取当前纪元毫秒数与除以 1000 消除小数。

标准推荐实现:Math.floor + Date.now()

// 1. 获取当前时间戳(秒级)
const timestampInSeconds = Math.floor(Date.now() / 1000);

console.log(timestampInSeconds); 
// 示例输出: 1730421045
console.log(typeof timestampInSeconds); 
// 示例输出: "number"
console.log(String(timestampInSeconds).length); 
// 示例输出: 10

这一段代码执行时包含了三个明确的环节:

  • Date.now():ES5 引入的静态方法,直接返回当前时间距离 1970-01-01 00:00:00 UTC 的毫秒数值。它不需要实例化 Date 对象,避免了额外的内存分配与垃圾回收开销,性能最高。
  • / 1000:把时间单位由毫秒换算为秒,计算结果是一个带有三位小数的浮点数(例如 1730421045.892)。
  • Math.floor():向下取整函数,舍弃所有小数位,确保结果为一个纯整数。由于时间轴向前单调递增,当前秒尚未过完之前,毫秒均属于当前这一秒内,向下取整完全符合时间物理语义。
JS怎么获取秒级时间戳
图 2:获取并规整秒级时间戳的四个处理步骤与数据流动

三、获取指定日期的秒级时间戳

实际业务中除了获取“当前时间”,更多场景是需要把给定的时间字符串(如用户选择的生日、查询开始时间)转换为秒级时间戳。此时应使用 new Date(dateString).getTime()。

// 针对指定时间字符串或日期对象计算秒级时间戳
function getSecondsTimestamp(dateInput) {
  const date = dateInput ? new Date(dateInput) : new Date();
  const milliseconds = date.getTime();

  // 防御性校验:检查传入时间是否合法
  if (Number.isNaN(milliseconds)) {
    throw new Error('无效的日期格式');
  }

  return Math.floor(milliseconds / 1000);
}

// 示例调用:
console.log(getSecondsTimestamp('2026-11-01T08:30:00Z'));
// 示例输出: 1793521800

console.log(getSecondsTimestamp(new Date('2026-01-01')));
// 示例输出: 1767225600
重要注意事项:时区与日期字符串解析

如果传入 '2026-11-01'(仅有年月日),在不同运行环境可能被解析为 UTC 0点,也可能被解析为本地时区 0点。为了避免跨时区换算导致的几小时偏差,建议始终传递遵循 ISO 8601 标准且带有显式时区信息的字符串(如 '2026-11-01T00:00:00+08:00' 或末尾带 Z)。

四、四种取整方案对比与 2038 年溢出陷阱

在前端代码中,不少开发者会使用不同的语法对浮点秒进行取整。下表列出常见的四种方式:

语法写法 运行机制 代码示例(以 1730421045.892 为例) 综合评价与适用边界
Math.floor(ms / 1000) 向下取整 1730421045 强烈推荐。语义契合时间推移,无数值上限问题。
Math.trunc(ms / 1000) 向零截断(直接去掉小数) 1730421045 可用(ES6+)。对正数表现与 floor 一致;对负数(1970年之前)不同。
Math.round(ms / 1000) 四舍五入 1730421046 慎用。超过 500ms 会“提前踏入下一秒”,可能导致未来时间判断误报。
(ms / 1000) | 0 按位或(位运算截断) 1730421045(当前正常,2038年后错误) 不建议使用。存在严重的 32 位有符号整数溢出风险(Y2038 问题)。

警惕位运算 | 0 引发的“2038 年问题”

部分老项目或极度追求“简短”的代码中,常见 (Date.now() / 1000) | 0 这种写法。JavaScript 规范规定,所有位运算符(如 |、>>、~)在执行前都会把操作数隐式转换为 32 位带符号整型(Int32)。

32 位带符号整数的最大正数上限是 2^31 - 1 = 2,147,483,647。当时间到达 UTC 时间 2038 年 1 月 19 日 03:14:07 时,秒级时间戳将突破该数值,最高符号位翻转,导致时间戳瞬间变成负数 -2,147,483,648(倒退回 1901 年)。

JS怎么获取秒级时间戳
图 3:浮点数取整与 32 位整型位运算的时间安全边界与溢出对比

五、反向操作:如何将秒级时间戳转回 Date 对象

既然 JavaScript 的 Date 构造函数只认毫秒,那么当后端接口返回一个 10 位的秒级时间戳时,必须乘以 1000 再传入构造器,否则会被解释为 1970 年元旦当天最初几十天内的微弱偏移。

// 后端返回的 10 位秒级时间戳
const serverSeconds = 1730421045;

// 正确做法:补齐为 13 位毫秒数值
const dateObj = new Date(serverSeconds * 1000);

console.log(dateObj.toISOString());
// 示例输出: "2024-11-01T00:30:45.000Z"

console.log(dateObj.toLocaleString('zh-CN', { hour12: false }));
// 示例输出: 本地格式化日期时间(如 "2024/11/1 08:30:45")

六、联调常见错误与排查清单

在前后端联调时间戳的过程中,最容易遇到以下三类典型问题:

  • 位数错位导致“时间穿越”:如果前端漏掉了 / 1000,直接将 13 位的 Date.now() 发送给预设 10 位整数的数据库(例如 MySQL 的 INT(10) UNSIGNED 或某些后端时间解析库),字段可能会溢出或解析为公元 56000 多年;反之若后端给 10 位前端没 * 1000,解析结果必然是 1970 年 1 月。
  • 时区混淆与“重复加减 8 小时”:时间戳本质上是与时区无关的纯计数点(全局绝对时间)。无论你在东八区还是西五区,同一瞬间的秒级时间戳数值完全一致。只有在将其格式化展示为字符串时,才涉及本地时区的偏移加减。不要在获取时间戳时自行执行 + 8 * 3600,否则会导致绝对时间产生物理偏移。
  • 浮点数未取整:有些直接写 Date.now() / 1000 而未做取整,将带有小数字符串或浮点数直接提交给后端,后端解析整型时可能抛出 NumberFormatException 或类型校验失败。
JS怎么获取秒级时间戳
图 4:秒级时间戳的获取、计算、规整与还原全景速查对照

结语

JavaScript 获取秒级时间戳的核心本质是“毫秒到秒的降精度处理”。记住单一基准:使用 Math.floor(Date.now() / 1000) 处理当前时刻,使用 Math.floor(new Date(val).getTime() / 1000) 处理特定日期,弃用可能带来隐患的位运算语法,并在前后端交互时保持严格的 10 位长度与无时区认知,便可从根本上避免时间戳处理中的各类隐蔽缺陷。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章