【问题标题】:Consistently parse various date and time formats with Howard Hinnant's date library使用 Howard Hinnant 的日期库一致地解析各种日期和时间格式
【发布时间】:2021-12-21 14:35:44
【问题描述】:

我需要能够根据 ISO-8601 标准的子集解析和存储各种日期、时间或两者。

日期采用以下格式:

  • YYYY
  • YYYY-mm
  • 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 不需要更改类型。这可能吗?

【问题讨论】:

  • 他们都使用什么类型的?这些似乎是不同的概念。考虑2012 + 1 12:30 + 1。非常不同的期望。您可以解析为每个元素可选的结构,但这没有用,因为操作没有意义。你可以考虑一个变体,但同样,似乎更紧迫的问题是,“然后你用它做什么?”
  • 我在想他们都可以使用 sys_time 类型。也许它可以假设一个没有日期的时间是那个时代过去的时间。没有一个月或一天的一年只会假设它是第一个月或第一天。
  • @user17360045: "我宁愿能够解析和存储同一类型中的任何格式。" 如果 Chrono 有一个总体设计原则,那就是就时间而言,没有一种正确的类型适用于所有事物。强迫用户意识到这一点是一个非常好的主意。强迫用户知道一年与一个完整的时间点不同是好的。

标签: c++ datetime c++20 chrono


【解决方案1】:

将它们全部存储在同一类型中的唯一方法是选择具有最多信息的一个 (sys_time&lt;microseconds&gt;),然后按照您显示的那样在部分类型中进行解析,并为那些未解析的值添加默认值.

例如:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-01
    • 2013-01-09
    相关资源
    最近更新 更多