【问题标题】:ways to record time in C++C++中记录时间的方法
【发布时间】:2020-04-24 04:48:31
【问题描述】:

在 C++ 中记录时间的最充分方法是什么(不是经过的时间,而是时间)

我现在正在尝试类似的东西

#include <iostream>
#include <ctime>
#include <ratio>
#include <chrono>

    int main ()
    {

      using namespace std::chrono;
      high_resolution_clock::time_point t1= high_resolution_clock::now();

      time_t tt=system_clock::to_time_t(t1);
      std::cout<<"Right now it is: " << ctime(&tt)<<std::endl;

    }

但我看到这需要(或者我理解错了??)我们从chrono 转换为使用to_time 的C 计时方式,所以不会破坏使用chrono 的意义吗?

我在搜索时发现的常见示例是关于经过时间的,但我想知道是否只记录时间,因为我对 C++11 不太熟悉

【问题讨论】:

  • 虽然this question 与您的不同,但答案也可能适用于此。
  • C++20 具有能够将system_clock 时间点分解为其日期和时间组件的功能,但尚无标准库实现实现它们。见P0355
  • C++20 还将具有使用std::format 和类似strftime 的格式字符串将system_clock 时间点格式化为字符串的功能,但同样没有标准库实现这些功能然而。见P0645/P1361

标签: c++ time chrono


【解决方案1】:

从 C++17 开始,std::chrono 除了将 time_point 转换为 time_t 并使用日期/时间格式之外,没有任何工具可以轻松地将 std::chrono::system_clock::time_point 分解为其日历日期和挂钟时间从 C 继承的功能。

可能只使用std::chrono,但并不简单。例如,这样的事情可以从std::chrono::system_clock::time_point 获取挂钟时间:

std::string time_of_day(const std::chrono::system_clock::time_point& time_point)
{
    using days = std::chrono::duration<int, std::ratio<86400>>;
    auto midnight = std::chrono::floor<days>(time_point);
    auto time_since_midnight = time_point - midnight;
    auto hours = std::chrono::floor<std::chrono::hours>(time_since_midnight);
    auto minutes = std::chrono::floor<std::chrono::minutes>(time_since_midnight - hours);
    auto seconds = std::chrono::floor<std::chrono::seconds>(time_since_midnight - minutes - hours);

    std::ostringstream oss;
    oss << hours.count() << ":" << std::setw(2) << std::setfill('0') << minutes.count() << ":" << seconds.count();
    return oss.str();
}

int main() {
    std::cout << time_of_day(std::chrono::system_clock::now());
}

Live Demo

这一点都不简单,我敢肯定我忽略了一些极端情况,但它只使用 std::chrono 设施。


C++20 将介绍几种更容易做到这一点的方法。在撰写本文时,尚未实现任何标准库实现。


首先,如果您想要完整的日期/时间,将会有一个重载的operator&lt;&lt;(std::ostream&amp;, const std::chrono::system_clock::time_point&amp;) 会为您格式化并打印出来:

int main() {
    std::cout << std::chrono::system_clock::now();
}

如果你只想要time_pointstd::chrono::day_month_yearstd::chrono::time_of_day的日期或时间部分,可以用朋友来分解time_point

例如,上面的time_of_day 函数可以更简单地像这样完成:

std::chrono::time_of_day time_of_day(const std::chrono::sytem_clock::time_point& time_point)
{
    auto midnight = std::chrono::floor<std::chrono::days>(time_point);
    return std::chrono::time_of_day{time_point - midnight};
}

int main() {
    std::cout << time_of_day(std::chrono::system_clock::now());
}

请参阅P3055 了解更多信息。


另一种方法是新的std::format 系列函数。将有一个std::formatter specialization for std::chrono::system_clock::time_point,它可以让您使用类似strftime 的格式字符串将time_point 格式化为字符串。例如,以下输出将与前两个 time_of_day 函数非常相似(如果不相同):

int main() {
    std::cout << std::format("{%T}", std::chrono::system_clock::now());
}

请参阅P0645P1361 了解更多信息。

【讨论】:

    【解决方案2】:

    auto t1 = system_clock::now(); 是解决方法

    时间点是

    template<
        class Clock,
        class Duration = typename Clock::duration
    > class time_point;
    

    system_clock::to_time_t 想要time_point&lt;system_clock&gt; 类型,但您提供完全不同的类型time_point&lt;high_resolution_clock&gt;

    【讨论】:

    • 在某些实现中(尤其是 libstdc++,有时还有 libc++),std::chrono::high_resolution_clockstd::chrono::system_clock 的别名。
    • 是的,像gcc的libstdc++,但是作者没有指定编译器和库
    【解决方案3】:

    阅读link下的注释

    注意事项

    high_resolution_clock 在不同的标准库实现中的实现不一致,应避免使用它。它通常只是 std::chrono::steady_clock 或 std::chrono::system_clock 的别名,但它是哪一个取决于库或配置。当它是一个 system_clock 时,它不是单调的(例如,时间可以倒退)。比如gcc的libstdc++是system_clock,MSVC是steady_clock,clang的libc++是依赖配置。

    通常应该直接使用 std::chrono::steady_clock 或 std::chrono::system_clock 而不是 std::chrono::high_resolution_clock:使用 stable_clock 进行持续时间测量,使用 system_clock 进行挂钟时间。

    int main()
    {
        using namespace std::chrono;
        auto nowTime = std::chrono::system_clock::now();
        auto tt = system_clock::to_time_t(nowTime);
        std::cout << "Right now it is: " << ctime(&tt) << std::endl;
    }
    

    【讨论】:

      【解决方案4】:

      最好的表现方式是:

      #include <stdint.h>
      
      uint64_t get_time_us() {
        struct timeval tv {0, 0};
        gettimeofday(&tv, NULL);
        return tv.tv_sec * 1000000 + tv.tv_usec; // microsecond
      }
      uint64_t t0 = get_time_us();
      // do_something
      uint64_t t1 = get_time_us();
      int time_cost = t1 - t0;
      

      对于 C++11:

      std::chrono::high_resolution_clock::time_point t1, t2
      t1 = std::chrono::high_resolution_clock::now();
      // do_something
      t2 = std::chrono::high_resolution_clock::now();
      int time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count(); // ms
      // int time_us = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count(); // us
      

      提升:

      #include <date_time/posix_time/posix_time.hpp>
      boost::posix_time::ptime t1(boost::posix_time::microsec_clock::universal_time());
      // do_something
      boost::posix_time::ptime t2(boost::posix_time::microsec_clock::universal_time());
      boost::posix_time::time_duration diff(t2 - t1);
      int micro_sec = diff.total_microseconds();
      

      【讨论】:

        猜你喜欢
        • 2011-08-25
        • 1970-01-01
        • 1970-01-01
        • 2020-11-25
        • 2013-07-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多