Dre*_*kes 41 c++ date-parsing datetime-parsing c++11
考虑格式的历史日期字符串:
Thu Jan 9 12:35:34 2014
Run Code Online (Sandbox Code Playgroud)
我想将这样的字符串解析为某种C++日期表示,然后计算从那时起经过的时间量.
从结果持续时间我需要访问秒数,分钟数,小时数和天数.
这可以用新的C++ 11 std::chrono
命名空间来完成吗?如果没有,我今天该怎么办呢?
我正在使用g ++ - 4.8.1,但据推测答案应该只针对C++ 11规范.
Sim*_*ple 64
std::tm tm = {};
std::stringstream ss("Jan 9 2014 12:35:34");
ss >> std::get_time(&tm, "%b %d %Y %H:%M:%S");
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&tm));
Run Code Online (Sandbox Code Playgroud)
版本5之前的GCC没有实现std::get_time
.你也应该写:
std::tm tm = {};
strptime("Thu Jan 9 2014 12:35:34", "%a %b %d %Y %H:%M:%S", &tm);
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&tm));
Run Code Online (Sandbox Code Playgroud)
How*_*ant 13
旧问题的新答案.新答案的基本原理:问题是从原始形式编辑的,因为当时的工具无法准确处理所要求的内容.由此产生的接受答案给出了与原始问题所要求的略有不同的行为.
我不是想放下接受的答案.这是一个很好的答案.只是C API 如此令人困惑,以至于不可避免会出现这样的错误.
最初的问题是解析"Thu, 9 Jan 2014 12:35:34 +0000"
.很明显,目的是解析表示UTC时间的时间戳.但是strptime
(它不是标准的C或C++,但是POSIX)不会解析尾随的UTC偏移量,表明这是一个UTC时间戳(它将格式化%z
,但不解析它).
然后编辑这个问题来询问"Thu Jan 9 12:35:34 2014"
.但是没有编辑这个问题来澄清这是一个UTC时间戳,还是计算机当前本地时区的时间戳.接受的答案隐含地假设时间戳代表计算机的当前本地时区,因为使用了std::mktime
.
std::mktime
不仅可以将字段类型tm
转换为串行类型time_t
,还可以执行从计算机本地时区到UTC的偏移调整.
但是,如果我们想要解析UTC时间戳作为原始(未编辑的)问题,该怎么办?
今天可以使用这个更新的免费开源库来完成.
#include "date.h"
#include <iostream>
#include <sstream>
int
main()
{
using namespace std;
using namespace date;
istringstream in{"Thu, 9 Jan 2014 12:35:34 +0000"};
sys_seconds tp;
in >> parse("%a, %d %b %Y %T %z", tp);
}
Run Code Online (Sandbox Code Playgroud)
这个库可以解析%z
.并且date::sys_seconds
只是一个typedef:
std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>
Run Code Online (Sandbox Code Playgroud)
这个问题还要求:
从结果持续时间我需要访问秒数,分钟数,小时数和天数.
那部分仍未得到答复.以下是使用此库的方法.对于这部分,我还将使用第二个仅限标题的库"chrono_io.h"
:
#include "chrono_io.h"
#include "date.h"
#include <iostream>
#include <sstream>
int
main()
{
using namespace std;
using namespace date;
istringstream in{"Thu, 9 Jan 2014 12:35:34 +0000"};
sys_seconds tp;
in >> parse("%a, %d %b %Y %T %z", tp);
auto tp_days = floor<days>(tp);
auto hms = make_time(tp - tp_days);
std::cout << "Number of days = " << tp_days.time_since_epoch() << '\n';
std::cout << "Number of hours = " << hms.hours() << '\n';
std::cout << "Number of minutes = " << hms.minutes() << '\n';
std::cout << "Number of seconds = " << hms.seconds() << '\n';
}
Run Code Online (Sandbox Code Playgroud)
floor<days>
将秒精度截断time_point
为天精度 time_point
.如果time_point
从中减去天数精度tp
,则会留下一个duration
表示自午夜(UTC)以来的时间.
工厂函数make_time
接受任何duration
(在这种情况下是从午夜开始的时间)并创建一个{hours, minutes, seconds}
字段类型,每个字段都有getter.如果持续时间的精度小于秒,则此字段类型也将具有亚秒的getter.
最后,使用"chrono_io.h"
,可以打印出所有这些持续时间.此示例输出:
Number of days = 16079[86400]s
Number of hours = 12h
Number of minutes = 35min
Number of seconds = 34s
Run Code Online (Sandbox Code Playgroud)
该[86400]s
代表的单位duration
有天精度.所以2014-01-09是1970-01-01之后的16079天.
归档时间: |
|
查看次数: |
29946 次 |
最近记录: |