我正在尝试使用Boost的日期时间库以自定义格式解析日期/时间字符串。我试图使用的格式相当不寻常,因为它包含Posix时区描述字符串。库docs的clearly state有一个标志(%ZP
)可用于处理Posix时区字符串的输入和输出。我试图解析的值来自Web浏览器,而不是编写JS来执行区域字符串中指定的转换然后以UTC格式发送到服务器,我宁愿只是在服务器端执行(因为Boost应该很容易做到这一点)。显然,如果有效,我不会在这里发帖。此代码抛出boost::bad_lexical_cast
,其值为“源类型值无法解释为目标”。
using namespace boost::posix_time;
using namespace boost::local_time;
using namespace boost::gregorian;
std::istringstream ss("1989-11-09T15:30:42.005;PST-8PDT,M3.2.0,M11.1.0");
ss.exceptions(std::ios_base::failbit);
local_time_input_facet* facet = new local_time_input_facet("%Y-%m-%dT%H:%M:%S%F;%ZP");
ss.imbue(std::locale(ss.getloc(), facet));
local_date_time ldt(not_a_date_time);
ss >> ldt; // do the parse
std::cout << ldt.to_string();
但是,如果用"%Y-%m-%dT%H:%M:%S%F;"
替换格式字符串,则解析成功(当然它会在错误的时区输出一个值)。
知道我做错了什么吗? %ZP
标志的文档没有示例,因此我不确定它应该如何使用。
答案 0 :(得分:1)
我认为您的格式字符串应如下所示:%Y-%m-%dT%H:%M:%s *;%ZP
%s *
将匹配秒和小数秒。有了这个改变,上面的代码运行,虽然我得到的输出是:
1989-Nov-09 15:30:42.005000 ST
不确定为什么它会显示ST
而不是PST
,但是时区信息会被正确解析,如果您将日期更改为例如11月,那么它将报告{{1} }。
编辑:时区对象的描述是here。
好吧,从解决这个问题看来,解析错误似乎是由PDT
的存在引起的,将其从原始字符串中删除,使其变为:
;
将格式字符串更改为:
std::istringstream ss("1989-10-16T15:30:42.005 PST-8PDT,M3.2.0,M10.2.0");
正确报告:
local_time_input_facet* facet = new local_time_input_facet("%Y-%m-%d %H:%M:%s %ZP");
如果再次将输入字符串更改为:
1989-Oct-16 15:30:42.005000 PST
输出再次正确:
std::istringstream ss("1989-10-16T15:30:42.005 PST-8PDT,M3.2.0,M11.1.0");
这告诉我,这确实是对字符串中嵌入的时区信息的尊重......所以有趣的问题是,如果有1989-Oct-16 15:30:42.005000 PDT
,为什么会发生骚扰?
进一步更新,似乎输入字符串只能包含字母数字,集合;
中的字符和空格 - 在小数位后 - 即你不能将时区信息内容与除了我之外的任何字符分开如上所列(它并非详尽无遗,没有时间对所有人进行测试!)