【问题标题】:How do I convert YYYY/MM/DD HH:MM:SS to std::chrono::system_clock::time_point?如何将 YYYY/MM/DD HH:MM:SS 转换为 std::chrono::system_clock::time_point?
【发布时间】:2015-07-29 21:48:11
【问题描述】:

我正在从板外实时时钟芯片获取 YYYY/MM/DD HH:MM:SS 组件。我想将其转换为std::chrono::system_clock::timepoint,以便我可以获得自纪元以来的秒数并更新操作系统的时间。

我想使用Howard Hinnant 建议的date 库来执行此转换。

我会直觉地做这样的事情:

date::year_month_day ymd = ...;
date::time_of_day tod = ...;
auto sysTime = date + tod;

但我没有看到适当的operator+ 重载。我错过了什么吗?

这种类型转换的另一个用例是将日历日期和时间转换为std::chrono::timepoint,我可以将其传递给boost::asio::steady_timer

【问题讨论】:

    标签: c++ datetime c++11 chrono


    【解决方案1】:

    通常time_of_day 仅用于将持续时间格式化为hh:mm:ss.fff 以供输出。但是可以将time_of_day 变回std::chrono::duration

    auto tod = make_time(hours{17} + minutes{16} + seconds{45});  // time_of_day
    auto d = seconds(tod);                                        // seconds
    

    在 C++14 中,我会使用更简洁的:17h + 16min + 45s,但正如您提到的,您使用的是 C++11,我将坚持使用 C++11 代码。

    year_month_day 可以通过以下方式转换为 sys_days

    auto ymd = jul/29/2015;
    auto dp = sys_days{ymd};
    

    sys_days 只不过是system_clock::time_point,但分辨率为days 而不是microsecondsnanoseconds

    然后您可以添加sys_daysduration 并将其分配给system_clock::time_point。把它们放在一起:

    #include "date.h"
    #include <iostream>
    
    int
    main()
    {
       using namespace date;
       using namespace std::chrono;
       auto ymd = jul/29/2015;
       auto tod = make_time(hours{17} + minutes{16} + seconds{45});
       system_clock::time_point tp =  sys_days(ymd) + seconds(tod);
    }
    

    在这个简化的示例中,无需通过time_of_day,您可以直接使用durations:

    #include "date.h"
    #include <iostream>
    
    int
    main()
    {
       using namespace date;
       using namespace std::chrono;
       auto ymd = jul/29/2015;
       system_clock::time_point tp = sys_days(ymd)
                                   + hours{17} + minutes{16} + seconds{45};
    }
    

    要记住的主要事情是sys_days 只是一个粗略的system_clock::time_point,当你从year_month_day 转换为year_month_day 时,你就完全在std::chrono 系统中,可以做任何你想做的事情time_points 和 durations 从那里开始。

    【讨论】:

    • auto ymd = jul/29/2015; 这是什么怪物 :(
    • 这不是怪物,它是一个明确的日期文字。如果您想更像 ISO-8601,可以使用 2015_y/7/29 代替。太糟糕了 2015_y/09/29 不会工作,而 2015_y/07/29 会。 ;)
    • @LightnessRacesinOrbit:我选择了全球使用的三种排序中的一种,我觉得很舒服。请使用 Ville 演示的任何一个你觉得舒服的。 :-)
    • @VilleVoutilainen:是的,这种形式是明确的,但我想我们很久以前就同意,任何形式的 m/d/y 在一般情况下都是愚蠢、危险和令人困惑的。即使您已经消除了其中一个组件的歧义!让我们坚持使用 y/m/d 或 d/m/y 或 y-m-d eh ;p 对这些新的日期文字不太熟悉;乍一看,它们看起来很容易出错。
    • @LightnessRacesinOrbit:请参阅en.wikipedia.org/wiki/Date_format_by_country 了解这个星球上的人们使用的“日期字节序”。另请参阅 howardhinnant.github.io/date_v2.html 以了解有关这些日期文字容易出错的说明。具体来说,该库旨在在编译时捕获这些类型的错误。此外,operator-() 不用于此目的,因为它在编码日期算术时很容易引入运行时错误。 operator/() 具有正确的优先级和语法以避免此类错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-16
    相关资源
    最近更新 更多