JS获取当前时间戳:Date.now()标准用法与兼容写法

作者:异步漫步时间:2026-11-04 16:22:14浏览:123

详细讲解JavaScript中使用Date.now()获取当前毫秒时间戳的标准方法,以及在不支持ES5环境下的兼容替代写法,附带完整代码示例与性能对比。

在JavaScript中获取当前时间戳,最直接的方式是调用 Date.now(),它返回从1970年1月1日00:00:00 UTC到当前时刻的毫秒数。这是ES5规范引入的静态方法,现代浏览器和Node.js都已支持。如果需要兼容IE8等老旧环境,则要使用 new Date().getTime() 或一元加号写法。本文依次讲解标准用法、兼容写法、两者的差异,以及实际开发中的使用场景。

什么是时间戳

时间戳(Timestamp)是一个数值,表示某个时刻与一个固定起点之间经过的时间长度。JavaScript使用的起点是UTC时间1970年1月1日零点,这个起点通常叫做Unix纪元(Unix Epoch)。JavaScript的时间戳单位是毫秒,而许多后端语言和API使用秒级时间戳,两者相差1000倍,在前后端交互时需要注意换算。

例如,毫秒时间戳 1698912000000 对应的秒级时间戳是 1698912000,表示2023年11月2日16:00:00 UTC。

JS获取当前时间戳:Date.now()标准用法与兼容写法

图1:JavaScript 时间戳的含义——从 Unix 纪元到当前时刻的毫秒数

Date.now() 标准用法

Date.now() 是 Date 构造函数上的静态方法,不需要创建 Date 实例就能直接调用。它返回一个整数,表示调用那一刻的毫秒时间戳。

var timestamp = Date.now();
console.log(timestamp); // 示例输出:1698912345678

这个方法没有参数,也没有副作用,每次调用时根据系统时钟返回当前值。它最早在ECMAScript 5(2009年发布)中被加入规范,目前所有主流浏览器(Chrome、Firefox、Safari、Edge)以及Node.js全部支持。

与 new Date().getTime() 的关系

Date.now() 在功能上等价于 new Date().getTime(),两者返回的数值相同。区别在于 Date.now() 不创建 Date 对象,直接返回数值,少了一次对象分配和垃圾回收。在密集调用的场景下,比如记录每帧渲染耗时或高频埋点,这个差异会产生可观测的性能区别。

// 两种写法返回值相同
console.log(Date.now());            // 1698912345678
console.log(new Date().getTime());  // 1698912345678

常见使用场景

计算代码执行耗时是最常见的用法。在代码段前后各调用一次 Date.now(),相减得到毫秒数:

var start = Date.now();

// 模拟耗时操作
for (var i = 0; i < 1000000; i++) {
  Math.sqrt(i);
}

var end = Date.now();
console.log('耗时:' + (end - start) + ' 毫秒');
// 示例输出:耗时:12 毫秒

生成简易唯一标识时,可以将时间戳与随机数拼接。不过要注意,在同一毫秒内多次调用 Date.now() 会得到相同值,因此它不适合作为严格唯一ID的唯一来源:

var simpleId = Date.now().toString(36) + Math.random().toString(36).slice(2, 7);
console.log(simpleId); // 示例输出:"lnj5k3d8x2f"

接口请求加时间戳防缓存也很常见。将时间戳追加到URL参数中,可以绕过浏览器对GET请求的缓存:

var url = '/api/data?t=' + Date.now();
// 每次请求的URL不同,浏览器不会使用缓存结果

兼容写法

如果代码需要运行在IE8或更早的浏览器中,Date.now() 会报错,因为这些环境不支持ES5的这个方法。以下是几种替代方案。

new Date().getTime()

这是最直观的替代写法。getTime() 从JavaScript诞生之初就存在,兼容所有版本的浏览器:

var timestamp = new Date().getTime();
console.log(timestamp); // 1698912345678

它的缺点是每次调用都会创建一个新的 Date 对象。如果只需要时间戳数值,这个对象创建是多余的。

一元加号 +new Date()

将一元加号 + 放在 new Date() 前面,JavaScript引擎会对 Date 对象进行 valueOf() 转换,结果就是毫秒时间戳:

var timestamp = +new Date();
console.log(timestamp); // 1698912345678

这种写法更简短,但可读性不如 getTime(),团队协作时建议根据代码规范选择。本质上它和 getTime() 一样会创建 Date 对象。

Polyfill方式

如果项目中大量使用 Date.now(),又需要兼容老浏览器,可以在代码入口处添加一段Polyfill,让老环境也能正常调用 Date.now():

if (!Date.now) {
  Date.now = function () {
    return new Date().getTime();
  };
}

这段代码检查 Date.now 是否存在,不存在时用 getTime() 实现一个。之后业务代码可以统一使用 Date.now(),不需要到处写兼容判断。MDN官方文档也推荐这种Polyfill写法。

JS获取当前时间戳:Date.now()标准用法与兼容写法

图2:三种获取时间戳写法在兼容性、性能和可读性上的对比

毫秒时间戳与秒级时间戳的转换

JavaScript的 Date.now() 返回毫秒级时间戳,而PHP的 time()、Python的 time.time()(取整后)、MySQL的 UNIX_TIMESTAMP() 等返回的都是秒级时间戳。前后端交互时经常需要转换。

// 毫秒转秒(取整)
var msTimestamp = Date.now();           // 1698912345678
var secTimestamp = Math.floor(msTimestamp / 1000);  // 1698912345

// 秒转毫秒
var fromServer = 1698912345;
var msValue = fromServer * 1000;        // 1698912345000

用 Math.floor() 而不是 parseInt() 做除法取整,原因是 parseInt 设计上是解析字符串的函数,传入数值时会先转成字符串再解析,虽然结果相同但语义不准确。也不要用位运算 |0 取整,因为位运算会把数值转为32位有符号整数,时间戳早已超出其范围。

注意:timestamp | 0 或 timestamp >> 0 会溢出。JavaScript时间戳动辄十三位数字,远超32位整数的最大值2147483647,位运算会产生错误结果。

Date.now() 与 performance.now() 的区别

浏览器还提供了 performance.now() 方法,它和 Date.now() 都能测量时间,但有本质区别:

特性Date.now()performance.now()
返回值毫秒整数微秒精度的浮点数
起点Unix纪元(1970年)页面导航开始时刻
受系统时钟调整影响是否
适用场景记录时间点、生成标识精确性能测量

performance.now() 使用的是单调递增时钟,不受用户修改系统时间或NTP校时的影响,精度可达微秒级。如果目的是测量代码执行耗时,performance.now() 更准确。但如果需要一个代表"当前是什么时候"的值,或者需要和后端时间做比较,应该使用 Date.now()。

// performance.now() 用法
var t0 = performance.now();
// 执行操作...
var t1 = performance.now();
console.log('耗时:' + (t1 - t0).toFixed(2) + ' 毫秒');
// 示例输出:耗时:0.35 毫秒
JS获取当前时间戳:Date.now()标准用法与兼容写法

图3:两种时间测量API的核心区别与各自适用场景

实际开发中的选择建议

把前面讨论的内容整理成具体的决策路径:

第一步:确认用途。如果是获取一个代表"当前时刻"的数值,用于存储、传输或比较,使用 Date.now()。如果是测量两段代码之间的耗时,优先使用 performance.now(),它更精确且不受系统时钟调整影响。

第二步:确认运行环境。如果项目只运行在现代浏览器和Node.js中(这是目前大多数项目的情况),直接使用 Date.now() 即可。如果需要兼容IE8及更早版本,在入口文件添加前述Polyfill。

第三步:确认精度需求。Date.now() 返回毫秒整数。如果需要和后端交互秒级时间戳,记得用 Math.floor(Date.now() / 1000) 转换。不要用位运算取整。

JS获取当前时间戳:Date.now()标准用法与兼容写法

图4:根据用途和环境选择获取时间戳方法的决策流程

完整示例:封装一个通用的时间戳工具函数

在实际项目中,可以封装一个简单的工具函数,既处理兼容性,也提供毫秒和秒两种格式的输出:

// timestamp.js
(function (global) {
  // Polyfill
  if (!Date.now) {
    Date.now = function () {
      return new Date().getTime();
    };
  }

  var Timestamp = {
    /** 获取毫秒时间戳 */
    ms: function () {
      return Date.now();
    },

    /** 获取秒级时间戳 */
    sec: function () {
      return Math.floor(Date.now() / 1000);
    },

    /** 计算两个毫秒时间戳之间的间隔(秒) */
    diffSec: function (start, end) {
      return Math.floor((end - start) / 1000);
    }
  };

  // 兼容 CommonJS 和浏览器全局
  if (typeof module !== 'undefined' && module.exports) {
    module.exports = Timestamp;
  } else {
    global.Timestamp = Timestamp;
  }
})(typeof window !== 'undefined' ? window : this);

使用方式:

// 浏览器中
console.log(Timestamp.ms());   // 1698912345678
console.log(Timestamp.sec());  // 1698912345

// 计算间隔
var start = Timestamp.ms();
// ... 执行操作 ...
var end = Timestamp.ms();
console.log('操作耗时 ' + Timestamp.diffSec(start, end) + ' 秒');

小结

Date.now() 是获取当前毫秒时间戳的标准方法,语义清晰且不创建多余对象。在不支持ES5的老旧环境中,通过 new Date().getTime() 或Polyfill可以实现同等功能。前后端交互时注意毫秒与秒的换算,始终使用 Math.floor() 取整而非位运算。需要高精度性能测量时,应使用 performance.now() 而非 Date.now()。

作者最新文章
相关文章
更多