最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can I convert performance.now() output to a UTC String? - Stack Overflow

programmeradmin0浏览0评论

In our code, we were previously calculating the difference between to events like so:

var beginTime = new Date();
// Do stuff
var endTime = new Date();
var duration = endTime.getTime() - beginTime.getTime();

console.log("Job began at " + beginTime.toUTCString()
            + " and took " + duration + " milliseconds.");

This results in a human-readable string:

Job began at Thu Sep 28 2017 11:17:33 GMT-0500 (Central Daylight Time) and took 7000 milliseconds.

We've decided to switch to High Resolution Time by using the more reliable performance.now(). However, we still want to be able have a human-readable UTC time string included.

Initially, we tried this:

var beginTime = performance.now();
// Do stuff
var endTime = performance.now();
var duration = endTime - beginTime;

console.log("Job began at " + new Date(beginTime).toUTCString() 
            + " and took " + duration + " seconds.");

We are finding that the duration is accurate, but new Date(performance.now()) results in an inaccurate UTC value (at the time of this writing, it provides a date nearly 50 years in the past).

Job began at Wed Dec 31 1969 20:10:46 GMT-0600 (Central Standard Time) and took 7000 milliseconds.

Is there a better way to convert the output of performance.now() to an accurate UTC string? It doesn't have to be the exact same format as new Date().toUTCString(), but it should be human-readable.

In our code, we were previously calculating the difference between to events like so:

var beginTime = new Date();
// Do stuff
var endTime = new Date();
var duration = endTime.getTime() - beginTime.getTime();

console.log("Job began at " + beginTime.toUTCString()
            + " and took " + duration + " milliseconds.");

This results in a human-readable string:

Job began at Thu Sep 28 2017 11:17:33 GMT-0500 (Central Daylight Time) and took 7000 milliseconds.

We've decided to switch to High Resolution Time by using the more reliable performance.now(). However, we still want to be able have a human-readable UTC time string included.

Initially, we tried this:

var beginTime = performance.now();
// Do stuff
var endTime = performance.now();
var duration = endTime - beginTime;

console.log("Job began at " + new Date(beginTime).toUTCString() 
            + " and took " + duration + " seconds.");

We are finding that the duration is accurate, but new Date(performance.now()) results in an inaccurate UTC value (at the time of this writing, it provides a date nearly 50 years in the past).

Job began at Wed Dec 31 1969 20:10:46 GMT-0600 (Central Standard Time) and took 7000 milliseconds.

Is there a better way to convert the output of performance.now() to an accurate UTC string? It doesn't have to be the exact same format as new Date().toUTCString(), but it should be human-readable.

Share Improve this question edited Mar 2, 2023 at 12:39 sideshowbarker 88.5k30 gold badges215 silver badges212 bronze badges asked Sep 28, 2017 at 16:49 ThunderforgeThunderforge 20.6k19 gold badges88 silver badges134 bronze badges 6
  • 2 performance.now() gives the time in ms since the navigation start. (and not since 1970) – Roland Starke Commented Sep 28, 2017 at 16:55
  • 2 They do different things. stackoverflow./questions/30795525/… – Thusitha Commented Sep 28, 2017 at 16:57
  • What are you doing that needs 5 microseconds of precision. Or did you just read a click bait article. – Darkrum Commented Sep 28, 2017 at 17:18
  • @Darkrum We actually needed surviving system clock manipulations, rather than the microsecond precision. Our actual jobs take longer than the example, and we had a few situations where a Windows Time Update ran during the job and spewed out bad results. – Thunderforge Commented Sep 28, 2017 at 18:45
  • @Thunderforge I see. But that's a fault of not having the server configured correctly and IMO not worth the effort. Just programmatically disable windows time updates during tests. – Darkrum Commented Sep 28, 2017 at 19:20
 |  Show 1 more ment

4 Answers 4

Reset to default 4

I would do it like this:

// mark the start time
performance.mark("start");

// ... 
//  later...
// ...
// mark the end time
performance.mark("end");

// create a measure called 'm' based on the two marks above
performance.measure("m", "start", "end");

// get the start mark, calculate its real-world timestamp using the time origin
var started = performance.getEntriesByName("start")[0];
var startedDt = new Date(performance.timing.navigationStart + started.startTime);

// get the measure we created above
var duration = performance.getEntriesByName("m")[0];
console.log(`job began on ${startedDt} and took ${duration.duration/1000.0} seconds`);

performance.clearMarks();

First, mark the start and end times for your duration measurement. Second, create a duration measurement.

Later on, you get your start and end marks, calculate the started date by bining the time origin with the start mark's timestamp. Lastly, clear the marks.

It's not strictly necessary to get the start mark... you can also calculate the real-world start timestamp from the measure m, which also has a startTime. I used the start mark, but either is valid.

In other words, you can also do this:

// get the measure we created above
var duration = performance.getEntriesByName("m")[0];
var startedDt = new Date(performance.timing.navigationStart + duration.startTime);

console.log(`job began on ${startedDt} and took ${duration.duration/1000.0} seconds`);

It can be done like this:

const t0 = performance.now();

// measured job here

const t1     = performance.now(),
      t0Date = new Date(performance.timing.navigationStart + t0).toUTCString();

console.log(`Job began at ${t0Date} and took ${t1 - t0} milliseconds.`);
/* Console formatting only */
.as-console-wrapper { top: 0; }

Note however that after performance.now() MDN page (emphasis mine):

(…) performance.timing.navigationStart + performance.now() will be approximately equal to Date.now().

For me, it's within one second of actual time start.

From the MDN,

unlike Date.now(), the values returned by Performance.now() always increase at a constant rate, independent of the system clock (which might be adjusted manually or skewed by software like NTP). Otherwise, performance.timing.navigationStart + performance.now() will be approximately equal to Date.now()

As the name implies performance.now() is to measure performance up to an accuracy of 5 microseconds between two tasks and not to keep the UNIX timeStamp.

performance.timing.navigationStart + performance.now() will be approximately equal to Date.now()

Read more about here.
https://developer.mozilla/en-US/docs/Web/API/Performance/now

This is not possible. The return values of performance.now do have the page load as their origin (0) value, and cannot be transformed into a date. According to the spec, you should be able to sum it with performance.timeOrigin to obtain a unix timestamp, however there doesn't seem to be any browser support for this.

If you want to know when your measuring started in wall clock time, I remend to store a conventional new Date/Date.now() timestamp as well.

发布评论

评论列表(0)

  1. 暂无评论