【问题标题】:C++11 Date / Times with Fractional Seconds带小数秒的 C++11 日期/时间
【发布时间】:2018-04-04 17:29:41
【问题描述】:

有人知道一种快速、便携的方法来解析包含小数秒的日期/时间字符串吗?

例如:

2017-10-23T07:23:08.78

到目前为止,我可以解析其他所有内容:

std::tm tm = {};
std::stringstream datestr("2017-10-23T07:23:08.78");
datestr >> std::get_time(&tm, "%Y-%m-dT%H:%M:%S.??");

上面的sn-p是从this帖子修改的。

This 其他帖子展示了两次解析年份的巧妙技巧。不幸的是,由于小数秒是我表示中的最后一个字段,它会覆盖我实际想要使用的任何有效字段。

参考文档 (here) 没有列出任何用于小数秒的转换说明符,也没有列出任何可用于匹配和丢弃任意数字的说明符(与 %t%n 用于空格相同。

明确地说,我完全可以放弃这部分精度。我不希望使用原始字符串函数来操作它,但这似乎是我能找到的唯一选择。

最后,这个字符串来自远程服务器,所以格式不受我控制。我的环境目前是 Posix,但我希望尽可能多地具有可移植性。


编辑:此问题已被标记为与this 重复。我不相信这是因为我的问题是专门关于解析/丢弃没有字符说明符的令牌的。这与使用例如%z 来解析时区(我也不感兴趣)的另一篇文章不同。我的问题专门针对解析,而不是对结果值的解释。

【问题讨论】:

标签: c++ c++11 datetime


【解决方案1】:

在上面 inxoy 的精彩评论的基础上,您可以使用 Howard Hinnant's, free, open-source, portable, datetime library 做到这一点:

#include "date/date.h"
#include <iostream>
#include <sstream>

int
main()
{
    std::stringstream datestr("2017-10-23T07:23:08.78");
    date::sys_time<std::chrono::milliseconds> tp;
    datestr >> date::parse("%FT%T", tp);
    if (datestr.fail())
        return 1;
    std::cout << date::format("%F %T\n", tp);
}

date::sys_time&lt;std::chrono::milliseconds&gt;std::chrono::system_clock::time_point 的类型别名,milliseconds 精度除外(您可以使用任何所需的精度)。

"%F""%Y-%m-%d" 的缩写,您可以互换使用。

如果您希望在 std::tmwiki page shows how to do this 以及大量其他示例代码中使用它。

上面的程序可移植输出:

2017-10-23 07:23:08.780

我可以改用:

std::chrono::system_clock::time_point tp;

这会将我的输出更改为:

2017-10-23 07:23:08.780000

%T 格式化程序将输出 time_point 所具有的任何精度,%T 解析器将解析与 time_point 一样多的十进制数字。

"date/date.h" 没有时区。它是严格意义上的 UTC(技术上是 Unix Time)。如果您需要使用时区(或闰秒),还有一个额外的 free, open-source IANA time zone library 可用,它建立在 "date/date.h" 之上。

【讨论】:

  • 在基本 STL 时间函数上使用库的额外时间(平均而言,作为粗略的百分比估计)是多少?我问,因为这将进入 API 响应代码,所以性能有点令人担忧。增加 10% 的时间不会破坏银行,但是,例如,解析时间加倍将是一个问题。
  • 如果您要比较的是从std::istringstream 解析的另一个解决方案,那么竞争非常激烈。主要开销可能是 C++ I/O 本身的实际使用。 date/date.h 是一个只有头文件的库(只有一个头文件),所以你很容易从 GitHub 下载并运行一个计时实验。只需指向标题即可。
  • 嗯...现在我想起来了,使用"%F" 超过"%Y-%m-%d" 将减少几个周期,因为解析器只需要解析一个命令而不是 3 个。
猜你喜欢
  • 2013-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多