JavaScript中获取时间戳的方法
技术背景
在JavaScript开发中,时间戳是一个非常重要的概念,它通常表示从某个固定时间点(如Unix纪元,即1970年1月1日00:00:00 UTC)到指定时间的毫秒数或秒数。时间戳在很多场景下都有应用,例如记录事件发生的时间、进行时间比较、缓存控制等。
实现步骤
1. 获取毫秒级时间戳
- 使用
Date.now()
方法:这是ES5引入的静态方法,直接返回当前时间距离Unix纪元的毫秒数。
1 2
| const timestampMs1 = Date.now(); console.log(timestampMs1);
|
- 使用一元运算符
+
:通过+ new Date()
将Date
对象转换为数值,即毫秒级时间戳。
1 2
| const timestampMs2 = +new Date(); console.log(timestampMs2);
|
- 调用
valueOf()
方法:new Date().valueOf()
同样返回当前时间的毫秒数。
1 2
| const timestampMs3 = new Date().valueOf(); console.log(timestampMs3);
|
- 调用
getTime()
方法:new Date().getTime()
也是获取毫秒级时间戳的常用方法。
1 2
| const timestampMs4 = new Date().getTime(); console.log(timestampMs4);
|
为了兼容IE8及更早版本的浏览器,可以为Date.now()
添加一个垫片(shim):
1 2 3
| if (!Date.now) { Date.now = function() { return new Date().getTime(); } }
|
2. 获取秒级时间戳(Unix时间戳)
- 使用
Math.floor()
方法:将Date.now()
返回的毫秒数除以1000并向下取整。
1 2
| const unixTimestamp1 = Math.floor(Date.now() / 1000); console.log(unixTimestamp1);
|
- 使用按位或运算符
| 0
:这种方法速度稍快,但可读性较差,且在2038年之后可能会出现问题。
1 2
| const unixTimestamp2 = Date.now() / 1000 | 0; console.log(unixTimestamp2);
|
3. 获取更高分辨率的毫秒级时间戳
使用performance.now()
方法结合performance.timing.navigationStart
可以获取更高分辨率的时间戳,但要注意performance.timing.navigationStart
已被弃用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var isPerformanceSupported = ( window.performance && window.performance.now && window.performance.timing && window.performance.timing.navigationStart );
var timeStampInMs = ( isPerformanceSupported ? window.performance.now() + window.performance.timing.navigationStart : Date.now() );
console.log(timeStampInMs, Date.now());
|
核心代码
以下是上述各种方法的汇总代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| const timestampMs1 = Date.now(); const timestampMs2 = +new Date(); const timestampMs3 = new Date().valueOf(); const timestampMs4 = new Date().getTime();
const unixTimestamp1 = Math.floor(Date.now() / 1000); const unixTimestamp2 = Date.now() / 1000 | 0;
var isPerformanceSupported = ( window.performance && window.performance.now && window.performance.timing && window.performance.timing.navigationStart );
var timeStampInMs = ( isPerformanceSupported ? window.performance.now() + window.performance.timing.navigationStart : Date.now() );
console.log(timestampMs1, timestampMs2, timestampMs3, timestampMs4); console.log(unixTimestamp1, unixTimestamp2); console.log(timeStampInMs);
|
最佳实践
- 兼容性考虑:如果需要兼容较旧的浏览器,建议使用
new Date().getTime()
或为Date.now()
添加垫片。 - 性能优化:在性能敏感的场景下,可以通过性能测试选择最快的方法,一般来说
Date.now()
在现代浏览器中性能较好。 - 时间精度:根据具体需求选择合适的时间精度,如只需要秒级时间戳,就使用相应的转换方法。
常见问题
- 2038年问题:使用按位或运算符
| 0
获取秒级时间戳时,在2038年之后可能会因为32位整数溢出而返回负数。建议使用Math.floor()
方法来避免这个问题。 - 浏览器兼容性:不同浏览器对时间戳获取方法的支持可能存在差异,需要进行充分的测试和兼容性处理。
- 时间精度问题:
performance.now()
虽然可以提供更高的时间精度,但在不同浏览器中的实现可能有所不同,且performance.timing.navigationStart
已被弃用,使用时需要注意。