使用 Howard Hinnant 的日期库一致地解析各种日期和时间格式
Consistently parse various date and time formats with Howard Hinnant's date library
我需要能够根据 ISO-8601 标准的子集解析和存储各种日期和/或时间。
日期的格式为:
- YYYY
- YYYY-毫米
- YYYY-mm-dd
时间格式为:
- HH:MM:SS
- HH:MM:SS.ffffff
如果同时定义了日期和时间,则还必须定义时区,如下所示:
- YYYY-mm-ddTHH:MM:SS.ffffff+ZZ:ZZ
- 例如:2012-03-04T05:06:07.123456+07:00
我尝试使用 Howard Hinnant 的日期库,与 C++20 标准中的相同。看来我需要使用特定类型来解析不同的格式,这有点烦人。我宁愿能够在同一类型中解析和存储任何格式。
为了说明问题:
sys_time<microseconds> sys_us;
microseconds us;
year_month ym;
year y;
std::istringstream iss;
iss.str("2012-03-04T05:06:07.123456+07:00");
iss >> date::parse("%FT%T%Ez", sys_us); // Only works with this type. (The others can't parse this much info.)
assert(!iss.fail());
iss.str("2012-03-04");
iss >> date::parse("%F", sys_us); // If the date has the full year, month, and day, this works.
assert(!iss.fail());
iss.str("2012-03");
// iss >> date::parse("%Y-%m", sys_us); // This fails; day is missing.
iss >> date::parse("%Y-%m", ym); // Works.
assert(!iss.fail());
iss.str("2012");
// iss >> date::parse("%Y", sys_us); // This fails.
// iss >> date::parse("%Y", ym); // Also fails; month is missing.
iss >> date::parse("%Y", y); // Works.
assert(!iss.fail());
iss.str("05:06:07.123456");
// iss >> date::parse("%T", sys_us); // Also fails; unhappy with missing date.
iss >> date::parse("%T", us); // Must use duration type for time instead.
assert(!iss.fail());
如果我可以 date::parse(format, obj)
并且 obj
不需要更改类型,那就更好了。这可能吗?
将它们全部存储在同一类型中的唯一方法是选择信息最多的一个 (sys_time<microseconds>
),然后按照您显示的那样在部分类型中进行解析并添加默认值这些值未被解析。
例如:
iss.str("05:06:07.123456");
iss >> date::parse("%T", us); // Must use duration type for time
sys_us = sys_days{year{0}/1/1} + us; // Add defaulted date
我需要能够根据 ISO-8601 标准的子集解析和存储各种日期和/或时间。
日期的格式为:
- YYYY
- YYYY-毫米
- YYYY-mm-dd
时间格式为:
- HH:MM:SS
- HH:MM:SS.ffffff
如果同时定义了日期和时间,则还必须定义时区,如下所示:
- YYYY-mm-ddTHH:MM:SS.ffffff+ZZ:ZZ
- 例如:2012-03-04T05:06:07.123456+07:00
我尝试使用 Howard Hinnant 的日期库,与 C++20 标准中的相同。看来我需要使用特定类型来解析不同的格式,这有点烦人。我宁愿能够在同一类型中解析和存储任何格式。
为了说明问题:
sys_time<microseconds> sys_us;
microseconds us;
year_month ym;
year y;
std::istringstream iss;
iss.str("2012-03-04T05:06:07.123456+07:00");
iss >> date::parse("%FT%T%Ez", sys_us); // Only works with this type. (The others can't parse this much info.)
assert(!iss.fail());
iss.str("2012-03-04");
iss >> date::parse("%F", sys_us); // If the date has the full year, month, and day, this works.
assert(!iss.fail());
iss.str("2012-03");
// iss >> date::parse("%Y-%m", sys_us); // This fails; day is missing.
iss >> date::parse("%Y-%m", ym); // Works.
assert(!iss.fail());
iss.str("2012");
// iss >> date::parse("%Y", sys_us); // This fails.
// iss >> date::parse("%Y", ym); // Also fails; month is missing.
iss >> date::parse("%Y", y); // Works.
assert(!iss.fail());
iss.str("05:06:07.123456");
// iss >> date::parse("%T", sys_us); // Also fails; unhappy with missing date.
iss >> date::parse("%T", us); // Must use duration type for time instead.
assert(!iss.fail());
如果我可以 date::parse(format, obj)
并且 obj
不需要更改类型,那就更好了。这可能吗?
将它们全部存储在同一类型中的唯一方法是选择信息最多的一个 (sys_time<microseconds>
),然后按照您显示的那样在部分类型中进行解析并添加默认值这些值未被解析。
例如:
iss.str("05:06:07.123456");
iss >> date::parse("%T", us); // Must use duration type for time
sys_us = sys_days{year{0}/1/1} + us; // Add defaulted date