使用C++20的chrono库/HH的日期库解析时间。

huangapple go评论70阅读模式
英文:

Parse time-of-day using C++20's chrono facilities / HH's date library

问题

我正在尝试解析形式为`"HH:MM"`的一天中的时间字符串,并接收从午夜以来的纳秒数。

只要我提供了一个日期和时间,我就可以成功解析,例如:

(我正在使用Howard Hinnant的日期库来替代C++20chrono,因为我的标准库(gcc 11.2)尚不支持此功能)

```cpp
#include <iostream>
#include <chrono>
#include <date/date.h>

int main()
{
    std::string str = "1970-01-01 08:00";
    std::string format = "%Y-%m-%d %H:%M";
    std::istringstream ss(str);

    std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> t;
    ss >> date::parse(format, t);

    if (ss.fail()) [[unlikely]]
        std::cerr << "解析失败\n";

    std::cout << "ns=" << t.time_since_epoch().count() << '\n';

    return 0;
}

我注意到chrono有一个“时分秒”类,hh_mm_ss,但我没有看到任何相关的解析功能。

是否可以使用格式(例如&quot;%H:%M&quot;)来解析一天中的时间字符串?


<details>
<summary>英文:</summary>

I am trying to parse a time-of-day string in the form of `&quot;HH:MM&quot;`, and receive back the nanoseconds since midnight.

So long as I provide a date **and a** time I can successfully parse it, eg:

(I am using Howard Hinnant&#39;s date library in lieu of C++20&#39;s chrono, as my std library (gcc 11.2) doesn&#39;t support this yet)

    #include &lt;iostream&gt;
    #include &lt;chrono&gt;
    #include &lt;date/date.h&gt;
    
    int main()
    {
        std::string str = &quot;1970-01-01 08:00&quot;;
        std::string format = &quot;%Y-%m-%d %H:%M&quot;;
        std::istringstream ss(str);
    
        std::chrono::time_point&lt;std::chrono::system_clock, std::chrono::nanoseconds&gt; t;
        ss &gt;&gt; date::parse(format, t);
    
        if (ss.fail()) [[unlikely]]
            std::cerr &lt;&lt; &quot;parse failed\n&quot;;
    
        std::cout &lt;&lt; &quot;ns=&quot; &lt;&lt; t.time_since_epoch().count() &lt;&lt; &#39;\n&#39;;
    
        return 0;
    }

I see that `chrono` has a &quot;time of day&quot; class, [`hh_mm_ss`](https://en.cppreference.com/w/cpp/chrono/hh_mm_ss), but I don&#39;t see any associated parsing functionality.

Is it possible to parse a time-of-day string using a format, eg, `&quot;%H:%M&quot;`?


</details>


# 答案1
**得分**: 1

这样做的方法是解析一个名为`nanoseconds`的`duration`,并将其解释为“午夜以来的时间段”:

```cpp
#include <iostream>
#include <chrono>
#include <date/date.h>

int main()
{
    std::string str = "08:00";
    std::string format = "%H:%M";
    std::istringstream ss(str);

    std::chrono::nanoseconds t;
    ss >> date::parse(format, t);

    if (ss.fail()) [[unlikely]]
        std::cerr << "parse failed\n";

    using date::operator<<;
    std::cout << "time of day = " << t << '\n';
}

这涉及以下步骤:

  • 截断您的字符串输入以获取所需的信息。
  • t的类型更改为nanoseconds

我使用了nanoseconds的流操作符,并更改了格式,以便输出为:

time of day = 28800000000000ns

如果您宁愿获得没有ns后缀的原始输出,那么您可以打印出t.count(),在这种情况下,无需使用using date::operator<<;


如果您想要非常复杂的话,可以创建自己的自定义chrono::time_point,具有“时间段”的语义。通常情况下这可能有些过度,但如果您想朝这个方向发展,可以参考以下链接的一些思路:https://stackoverflow.com/a/56727183/576911。

英文:

The way to do this is to parse a duration such as nanoseconds and interpret that as "time duration since midnight":

#include &lt;iostream&gt;
#include &lt;chrono&gt;
#include &lt;date/date.h&gt;

int main()
{
    std::string str = &quot;08:00&quot;;
    std::string format = &quot;%H:%M&quot;;
    std::istringstream ss(str);

    std::chrono::nanoseconds t;
    ss &gt;&gt; date::parse(format, t);

    if (ss.fail()) [[unlikely]]
        std::cerr &lt;&lt; &quot;parse failed\n&quot;;

    using date::operator&lt;&lt;;
    std::cout &lt;&lt; &quot;time of day = &quot; &lt;&lt; t &lt;&lt; &#39;\n&#39;;
}

This involves:

  • Truncate your string inputs to the desired information.
  • Change the type of t to nanoseconds.

I used the streaming operator for nanoseconds and changed the formatting so that the output is:

time of day = 28800000000000ns

If you would rather get your original output without the ns suffix, then you can print out t.count(), and in that case there is no need for the using date::operator&lt;&lt;;.


If you want to get really fancy you can create your own custom chrono::time_point that has the semantics of "time of day". That's usually overkill. But if you would like to head that direction, here's some thoughts on it: https://stackoverflow.com/a/56727183/576911.

huangapple
  • 本文由 发表于 2023年1月9日 18:55:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/75056260.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定