【问题标题】:Converting time in milliseconds since epoch to time in yy-dd-hh-ss format将自纪元以来的毫秒数转换为 yy-dd-hh-ss 格式的时间
【发布时间】:2021-10-21 19:56:42
【问题描述】:

我有一堆以微秒为单位的任务,下面的代码只打印到几秒钟(2021 年 10 月 21 日星期四 12:48:20 2021),所以比较 start 和 finish 的值总是最终给出 0。我希望能够以毫秒和微秒的顺序进行比较。有什么功能可以帮助解决这个问题吗?

另外,有没有办法将uint64_t current1 = std::chrono::system_clock::now().time_since_epoch().count(); 转换为time_t 以根据count() 打印出当前时间?

const auto p1 = std::chrono::system_clock::now();
    std::time_t now = std::chrono::system_clock::to_time_t(p1);
    std::cout << "now: " << std::ctime(&now);

【问题讨论】:

  • 至少在大多数实现中,time_t 的分辨率为一秒。
  • 查看en.cppreference.com/w/cpp/chrono,有很多标准工具可以处理亚秒级时间间隔(但time_t 不是其中之一,请考虑使用其他工具)。
  • 如果你比较“开始”和“结束”时间,你应该使用std::chrono::steady_clocksystem_clock 不能用于计时,因为就像挂钟一样,它们可以突然向前和向后跳跃。
  • 好的,有没有办法以日期时间的可读格式转换为打印 std::chrono::system_clock::now().time_since_epoch().count() ?
  • @learnzz 有没有回答您的问题?如果有,请考虑accepting吧。

标签: c++ chrono


【解决方案1】:

我建议完全跳过 C 计时 API。它容易出错并且不能处理亚秒级精度。

如果 UTC(相对于本地时间)没问题,那么有一个 header-only, open-source preview of C++20 可用于 C++11/14/17:

#include "date/date.h"
#include <chrono>
#include <iostream>

int
main()
{
    using date::operator<<;
    const auto p1 = std::chrono::system_clock::now();
    std::cout << "now: " << p1 << '\n';
}

输出:

now: 2021-10-21 20:28:15.754423

要将上述程序移植到 C++20(已在最新的 Visual Studio 中提供),只需删除 #include "date/date.h"using date::operator&lt;&lt;;

如果您需要本地时间,也可以在 C++20 中使用(在 VS 中提供),但 open-source preview of C++20 不再只是标题。存在一个需要编译的源文件,根据您的需要,可能需要下载 IANA tz 数据库。

#include "date/tz.h"
#include <chrono>
#include <iostream>

int
main()
{
    using namespace date;
    using namespace std::chrono;
    const auto p1 = system_clock::now();
    std::cout << "now: " << zoned_time{current_zone(), p1} << '\n';
}

输出:

now: 2021-10-21 16:28:15.754423 EDT

以上语法假定 C++17。对于 C++11/14,需要指定 zoned_time 的模板参数:zoned_time&lt;system_clock::duration&gt;

通过删除#include "date/tz.h"using namespace date;,将上述程序移植到C++20。

在任一程序中,您都可以使用以下方法截断到毫秒精度:

const auto p1 = floor<milliseconds>(system_clock::now());

【讨论】:

    【解决方案2】:

    time_t 通常是指定(整)秒的整数。

    您可以通过从 now 中减去整秒 time_t 来获得毫秒:

    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
                  p1 - std::chrono::system_clock::from_time_t(now)).count();
    

    或使用operator%:

    auto ms = std::chrono::time_point_cast<std::chrono::milliseconds>p1)
                 .time_since_epoch() % std::chrono::seconds(1);
    
    std::cout << ms.count();
    

    示例如何进行格式化:

    #include <chrono>
    #include <iostream>
    #include <iomanip>
    
    int main() {
        using Clock = std::chrono::system_clock;
        using Precision = std::chrono::milliseconds;
    
        auto time_point = Clock::now();
    
        // extract std::time_t from time_point
        std::time_t t = Clock::to_time_t(time_point);
    
        // output the part supported by std::tm
        std::cout << std::put_time(std::localtime(&t), "%FT%T."); // select format here
    
        // get duration since epoch
        auto dur = time_point.time_since_epoch();
    
        // extract the sub second part from the duration since epoch
        auto ss =
            std::chrono::duration_cast<Precision>(dur) % std::chrono::seconds{1};
    
        // output the millisecond part
        std::cout << std::setfill('0') << std::setw(3) << ss.count();
    }
    

    【讨论】:

    • 这是打印纪元时间 Wed Dec 31 16:05:07 1969。如何以毫秒为单位获取当前时间
    • @learnzz 您需要单独打印ms 部分。没有标准功能可以做到这一点。我的答案中的 ms 变量 保留剩余的毫秒数。来自p1
    • 另外,你知道从纪元到当前时间的秒数吗(可读) uint64_t current1 = std::chrono::system_clock::now().time_since_epoch().count();跨度>
    • @learnzz std::chrono::system_clock::from_time_t(seconds_since_epoch) 应该可以工作。
    • 这应该存储为什么类型的变量? std::chrono::system_clock::from_time_t(seconds_since_epoch)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-08
    • 2013-08-19
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 2012-03-08
    • 1970-01-01
    相关资源
    最近更新 更多