如何在Node.js中获得准时制?


Answers:


102

new Date().getTime()?这给您一个以毫秒为单位的时间戳,这是JS给您的最准确的时间戳。

更新:正如vaughan所述,process.hrtime()它可以在Node.js中使用-它的分辨率为纳秒,因此它的分辨率更高,这并不意味着它必须更精确。

PS .:为了更清楚一点,process.hrtime()返回一个元组,Array其中包含当前的高分辨率实时(以秒为单位,以纳秒为单位)


91
Date.now()请。
jAndy 2012年

50
使用process.hrtime()
vaughan

3
我必须同意。这个答案是完全错误的。请参阅以下@Meryn Stol的答案以获取正确答案。
贾斯汀·沃肯汀

11
process.hrtime()这些时间与过去的任意时间有关,与一天中的时间无关,因此不受时钟漂移的影响。主要用途是测量间隔之间的性能。因此,它没有给出当前时间
Alex

9
所有最重要的答案都是错误的。process.hrtime()不返回当前时间。

178

在Node.js中,可通过获得“高分辨率时间” process.hrtime。它返回一个数组,其中第一个元素的时间以秒为单位,第二个元素的剩余时间为纳秒。

要获取以毫秒为单位的当前时间,请执行以下操作:

var hrTime = process.hrtime()
console.log(hrTime[0] * 1000000 + hrTime[1] / 1000)

(感谢itaifrenkel指出上面的转换中的错误。)

在现代浏览器中,微秒级的时间可用performance.now。有关文档,请参见https://developer.mozilla.org/en-US/docs/Web/API/Performance/now

我已经基于实现了针对Node.js的此功能,process.hrtime如果您只想计算程序中两点之间的时差,则相对难以使用。参见http://npmjs.org/package/performance-now。根据规范,此函数报告的时间以毫秒为单位,但是它是一个浮点数,具有亚毫秒级的精度。

在此模块的2.0版中,报告的毫秒数是相对于启动节点进程的时间(Date.now() - (process.uptime() * 1000))。如果您想要类似的时间戳,则需要将其添加到结果中Date.now()。另请注意,您应该重新计算Date.now() - (process.uptime() * 1000)Date.now和两者process.uptime对于精确测量都是高度不可靠的。

要获得以毫秒为单位的当前时间,可以使用类似这样的东西。

var loadTimeInMS = Date.now()
var performanceNow = require("performance-now")
console.log((loadTimeInMS + performanceNow()) * 1000)

另请参阅:JavaScript是否提供高分辨率计时器?


27
应该注意的是,要进行基准测试,您可以传递前一个调用的结果process.hrtime()以获取差异。例如var startTime = process.hrtime();然后var diff = process.hrtime(startTime);
贾斯汀·沃肯汀

5
将秒转换为微秒时,请检查时间单位。console.log(hrTime [0] * 1000000 + hrTime [1] / 1000)
itaifrenkel 2014年

感谢您指出此错误,itaifrenkel!我已更正了转换代码。
Myrne Stol

2
require("performance.now")应该require("performance-now")吗?
UpTheCreek 2014年

5
process.hrtime()不返回当前时间。

21
now('milli'); //  120335360.999686
now('micro') ; // 120335360966.583
now('nano') ; //  120335360904333

已知now是:

const now = (unit) => {

  const hrTime = process.hrtime();

  switch (unit) {

    case 'milli':
      return hrTime[0] * 1000 + hrTime[1] / 1000000;

    case 'micro':
      return hrTime[0] * 1000000 + hrTime[1] / 1000;

    case 'nano':
      return hrTime[0] * 1000000000 + hrTime[1];

    default:
      return now('nano');
  }

};

14
process.hrtime()不返回当前时间。

你有哪一个?
Abdennour TOUMI'7

12

BigInt从Node.js 10.7.0开始支持该数据类型。(另请参阅博客文章公告)。对于这些受支持的Node.js版本,该process.hrtime([time])方法现在被视为“旧版”,由该process.hrtime.bigint()方法代替。

该方法的bigint版本会在中process.hrtime()返回当前的高分辨率实时图像bigint

const start = process.hrtime.bigint();
// 191051479007711n

setTimeout(() => {
  const end = process.hrtime.bigint();
  // 191052633396993n

  console.log(`Benchmark took ${end - start} nanoseconds`);
  // Benchmark took 1154389282 nanoseconds
}, 1000);

tl; dr

  • Node.js 10.7.0+-使用 process.hrtime.bigint()
  • 否则-使用 process.hrtime()


5

Node.js NanoTimer

我在process.hrtime函数调用之上为node.js编写了一个包装库/对象。它具有有用的功能,例如定时同步和异步任务,以秒,毫秒,微秒甚至是毫微秒指定,并遵循内置javascript计时器的语法,以使其熟悉。

计时器对象也是离散的,因此您可以根据需要拥有任意数量的对象,每个对象都可以运行自己的对象setTimeoutsetInterval进程。

它被称为nanotimer。看看这个!


2

要比精度更高Date.now(),但浮点精度为毫秒:

function getTimeMSFloat() {
    var hrtime = process.hrtime();
    return ( hrtime[0] * 1000000 + hrtime[1] / 1000 ) / 1000;
}

2
process.hrtime()不返回当前时间
Marc J. Schmidt

你是对的。来自文档:“这些时间是相对于过去的任意时间而言的,与一天中的时间无关,因此不受时钟漂移的影响。主要用途是测量间隔之间的性能” nodejs.org/api/process .html#process_process_hrtime_time
罗斯,

1

hrtime在一行中作为单个数字获取:

const begin = process.hrtime();
// ... Do the thing you want to measure
const nanoSeconds = process.hrtime(begin).reduce((sec, nano) => sec * 1e9 + nano)

Array.reduce,当给定单个参数时,将使用数组的第一个元素作为初始accumulator值。可以将其0用作初始值,这也可以使用,但是为什么要额外使用* 0


0

有绑定到系统gettimeofday()函数的npm软件包,该函数在Linux上返回微秒级的时间戳。搜索npm gettimeofday。调用C的速度比process.hrtime()


0

重写以帮助快速理解:

const hrtime = process.hrtime();     // [0] is seconds, [1] is nanoseconds

let nanoSeconds = (hrtime[0] * 1e9) + hrtime[1];    // 1 second is 1e9 nano seconds
console.log('nanoSeconds:  ' + nanoSeconds);
//nanoSeconds:  97760957504895

let microSeconds = parseInt(((hrtime[0] * 1e6) + (hrtime[1]) * 1e-3));
console.log('microSeconds: ' + microSeconds);
//microSeconds: 97760957504

let milliSeconds = parseInt(((hrtime[0] * 1e3) + (hrtime[1]) * 1e-6));
console.log('milliSeconds: ' + milliSeconds);
//milliSeconds: 97760957

来源:https : //nodejs.org/api/process.html#process_process_hrtime_time


0

我对此解决方案并不感到骄傲,但是您可以通过以下方式将时间戳记为微秒或纳秒

const microsecond = () => Number(Date.now() + String(process.hrtime()[1]).slice(3,6))
const nanosecond = () => Number(Date.now() + String(process.hrtime()[1]).slice(3))

// usage
microsecond() // return 1586878008997591
nanosecond()  // return 1586878009000645600

// Benchmark with 100 000 iterations
// Date.now: 7.758ms
// microsecond: 33.382ms
// nanosecond: 31.252ms

我知道:

  • 此解决方案仅与node.js配合使用
  • 这比慢3到10倍Date.now()
  • 奇怪的是,它看起来非常准确,hrTime似乎完全遵循js时间戳记。
  • 您可以替换Date.now()Number(new Date())以毫秒为单位获取时间戳

编辑:

这是一个用逗号表示微秒的解决方案,但是数字版本将由javascript本身取整。因此,如果每次都希望使用相同的格式,则应使用它的String版本。

const microsecondWithCommaString = () => (Date.now() + '.' + String(process.hrtime()[1]).slice(3,7))
const microsecondWithComma = () => Number(Date.now() + '.' + String(process.hrtime()[1]).slice(3,7))

microsecondWithCommaString() // return "1586883629984.8997"
microsecondWithComma() // return 1586883629985.966


-8

更好?

Number(process.hrtime().join(''))

3
这根本不起作用。不使用。由于这些值是整数,因此数组的第二个元素永远不会有固定的宽度。前导零不存在,不能作为字符串连接。
user.friendly

Number(process.hrtime()。map((n,i)=> i?('000000000'+ n).slice(-9):n).join(''))
Mike
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.