英文:
Parse time-of-day using C++20's chrono facilities / HH's date library
问题
我正在尝试解析形式为`"HH:MM"`的一天中的时间字符串,并接收从午夜以来的纳秒数。
只要我提供了一个日期和时间,我就可以成功解析,例如:
(我正在使用Howard Hinnant的日期库来替代C++20的chrono,因为我的标准库(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
,但我没有看到任何相关的解析功能。
是否可以使用格式(例如"%H:%M"
)来解析一天中的时间字符串?
<details>
<summary>英文:</summary>
I am trying to parse a time-of-day string in the form of `"HH:MM"`, 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's date library in lieu of C++20's chrono, as my std library (gcc 11.2) doesn't support this yet)
#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 << "parse failed\n";
std::cout << "ns=" << t.time_since_epoch().count() << '\n';
return 0;
}
I see that `chrono` has a "time of day" class, [`hh_mm_ss`](https://en.cppreference.com/w/cpp/chrono/hh_mm_ss), but I don't see any associated parsing functionality.
Is it possible to parse a time-of-day string using a format, eg, `"%H:%M"`?
</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 <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';
}
This involves:
- Truncate your string inputs to the desired information.
- Change the type of
t
tonanoseconds
.
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<<;
.
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论