【问题标题】:How do I get seconds since epoch as a double, given a time point?给定一个时间点,我如何获得自纪元以来的秒数作为双倍?
【发布时间】:2016-02-20 12:19:44
【问题描述】:

我有一个来自我正在使用的库的函数,它需要一个双精度作为参数。它需要传递一个纳秒类型的偏移量加上 sytem_clock::now()。到目前为止我有这个代码:

system_clock::time_point now = std::chrono::system_clock::now(); 
    auto timepointoffset = (now + desiredOffset);

我怎样才能使它成为双倍?

编辑:所以我需要补充一点,问题是我需要这样做而不会有丢失数据的风险。我有这个代码:

    system_clock::time_point now = std::chrono::system_clock::now(); 
    auto timepointoffset =  std::chrono::time_point_cast<std::chrono::nanoseconds>(now + desiredOffset);
    double value = timepointoffset.time_since_epoch().count();

问题是编译器说可能会丢失数据。

【问题讨论】:

  • 您在问题中没有提到 ntp。它是如何成为相关标签的?
  • 你试过double newTime = static_cast&lt;double&gt;(timepointoffset);或类似的东西吗?
  • 马特,我试过了,但它不起作用。

标签: c++ c++11 time chrono


【解决方案1】:

这个程序:

#include <chrono>
#include <cmath>
#include <iostream>

int
main()
{
    using namespace std::chrono;
    auto tp = system_clock::now() + 0ns;
    double t1 = tp.time_since_epoch().count();
    double t2 = std::nextafter(t1, INFINITY);
    std::cout << t2-t1 << '\n';
}

目前输出:

256

这意味着当前 double 不能准确表示自 1970-01-01 00:00:00 UTC 以来的纳秒数。双精度可以表示等于 256ns(大约四分之一微秒)的单位。

自 2006-07-14 23:58:24.606847232 以来一直如此。在此之前(有一段时间),double 可以表示精度为 128ns。

在 2043 年 1 月 25 日 23:56:49.213694464 UTC 时,double 将开始能够表示仅 512ns 的精度。

double 只能在 1969-09-18 18:00:01 到 1970-04-15 05:59:59 的大致范围内以纳秒精度存储 system_clock::time_point

此分析当然假设 IEEE 64 位双精度。

【讨论】:

    【解决方案2】:

    time_point 模板有一个成员函数time_point::time_since_epoch,它以duration 对象的形式返回自纪元以来的时间。 duration 是模板类型,函数返回的确切持续时间类型与time_pointDuration 模板参数相同。另一方面,system_clock::now() 返回的time_point 的类型是实现定义的。

    您希望时间具有特定的表示形式。为此,您必须具有所需类型的持续时间。在这种情况下,您需要std::duration&lt;double, std::ratio&lt;1&gt;&gt;。要获得time_since_epoch 返回的正确类型的持续时间,您可以使用std::chrono::duration_cast 进行转换。当您有正确表示的持续时间时,您可以使用duration 的成员函数count 来获取所需表示的值。

    【讨论】:

    • 感谢您的回答,我相信我按照您说的做了,但我仍然收到警告说可能会丢失数据。我做错了吗?
    • @Elijah 也许你是,或者你的代码可能有其他问题。确切的警告消息和它所指向的行应该可以揭示问题所在。
    【解决方案3】:
    std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(
      std::chrono::system_clock::now().time_since_epoch()).count() << std::endl;
    

    似乎是获得 long 的正确方法:http://en.cppreference.com/w/cpp/chrono/time_point/time_since_epoch 然后您可以将其转换为 double。

    【讨论】:

      【解决方案4】:

      您可以将timepointoffset 转换为std::time_t,然后将其转换为double:

      std::time_t offsetTimet = std::chrono::system_clock::to_time_t(timepointoffset);
      double offsetDouble = static_cast<double>(offsetTimet);
      

      请注意,std::time_t 通常是整数类型,there is no guarantee

      【讨论】:

        【解决方案5】:

        所以我需要补充一点,问题是我需要这样做而不会有丢失数据的风险。我有这个代码:

        一般来说没有办法做到这一点。当您从整数类型转换为浮点类型时,通常会丢失精度。使用floating point,位被分成尾数和指数。由于整数没有为指数分配位,因此表示该值的精度位通常较少。

        例如,从int64_t 转换为doubleint64_t 有 1 个符号位和 63 个值位。 double 有 1 个符号位、11 个指数位和 52 个尾数位。因此,从int64_t (63) 转换为 double (52),您最多可能会丢失 11 位信息。

        【讨论】:

          猜你喜欢
          • 2020-02-11
          • 1970-01-01
          • 2019-12-04
          • 2011-10-24
          • 2021-06-11
          • 2013-08-19
          • 1970-01-01
          • 2017-01-19
          • 2013-05-14
          相关资源
          最近更新 更多