【问题标题】:How can I convert performance.now() output to a UTC String?如何将 performance.now() 输出转换为 UTC 字符串?
【发布时间】:2017-09-28 16:49:32
【问题描述】:

在我们的代码中,我们之前是这样计算事件之间的差异的:

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.");

这会产生一个人类可读的字符串:

作业于 2017 年 9 月 28 日星期四 11:17:33 GMT-0500(中部夏令时)开始,耗时 7000 毫秒。

我们决定改用High Resolution Time,使用更可靠的performance.now()。但是,我们仍然希望能够包含人类可读的 UTC 时间字符串。

最初,我们尝试了这个:

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.");

我们发现持续时间是准确的,但 new Date(performance.now()) 导致 UTC 值不准确(在撰写本文时,它提供了近 50 年前的日期)。

作业开始于 1969 年 12 月 31 日星期三 20:10:46 GMT-0600(中部标准时间),耗时 7000 毫秒。

有没有更好的方法将performance.now() 的输出转换为准确的UTC 字符串?它不必与new Date().toUTCString() 的格式完全相同,但应该是人类可读的。

【问题讨论】:

  • performance.now() 以毫秒为单位给出导航开始的时间。 (不是自 1970 年以来)
  • 他们做不同的事情。 stackoverflow.com/questions/30795525/…
  • 你在做什么需要 5 微秒的精度。还是您刚刚阅读了一篇点击诱饵文章。
  • @Darkrum 我们实际上需要生存的系统时钟操作,而不是微秒精度。我们的实际工作比示例花费的时间更长,并且我们遇到了一些情况,即在工作期间运行 Windows 时间更新并产生不良结果。
  • @Thunderforge 我明白了。但这是没有正确配置服务器的错误,IMO 不值得付出努力。只需在测试期间以编程方式禁用 Windows 时间更新。

标签: javascript datetime high-resolution-time


【解决方案1】:

可以这样做:

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; }

但是请注意,在performance.now() MDN page(强调我的)之后:

(...)performance.timing.navigationStart + performance.now()大约等于Date.now()

对我来说,它在实际时间开始的一秒内。

【讨论】:

    【解决方案2】:

    我会这样做:

    // 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();
    

    首先,标记持续时间测量的开始时间和结束时间。其次,创建持续时间测量。

    稍后,您将获得开始和结束标记,通过将时间原点与开始标记的时间戳相结合来计算开始日期。最后,清除标记。

    获取开始标记并不是绝对必要的...您还可以从度量m 计算真实世界的开始时间戳,它也有一个startTime。我使用了开始标记,但任何一个都有效。

    换句话说,你也可以这样做:

    // 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`);
    

    【讨论】:

      【解决方案3】:

      来自 MDN,

      Date.now() 不同,Performance.now() 始终返回的值 以恒定速率增加,独立于系统时钟(其中 可以手动调整或通过 NTP 等软件进行调整)。除此以外, performance.timing.navigationStart + performance.now() 将是 约等于Date.now()

      顾名思义,performance.now() 是在两个任务之间以 5 微秒的精度测量性能,而不是保留 UNIX timeStamp

      performance.timing.navigationStart + performance.now() 将是 大约等于Date.now()

      在此处了解更多信息。
      https://developer.mozilla.org/en-US/docs/Web/API/Performance/now

      【讨论】:

        【解决方案4】:

        这是不可能的。 performance.now 的返回值确实有 page load as their origin (0) value并且不能转换为日期。根据规范,您应该能够将其与 performance.timeOrigin 相加以获得 unix 时间戳,但似乎没有任何浏览器支持。

        如果您想知道何时开始测量挂钟时间,我建议您也存储一个常规的new Date/Date.now() 时间戳。

        【讨论】:

        • 看起来performance.timeOriginHigh Resolution Time Level 1(2012 年 12 月提交)中不存在,但在 High Resolution Time Level 2(2017 年 8 月提交)中存在。正如你所说,浏览器似乎还不支持这一点。
        • @Thunderforge 正如 Thusita 所写,您可以使用 performance.timing.navigationStart 作为替身,尽管它并不完全准确。或者你自己计算一次,使用Date.now() - performance.now()
        猜你喜欢
        • 2022-11-23
        • 1970-01-01
        • 1970-01-01
        • 2012-08-04
        • 2019-02-22
        • 2020-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多