使用带有时区字符串的Boost日期时间库解析失败

时间:2011-01-26 00:30:16

标签: c++ parsing exception datetime boost

我正在尝试使用Boost的日期时间库以自定义格式解析日期/时间字符串。我试图使用的格式相当不寻常,因为它包含Posix时区描述字符串。库docsclearly 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标志的文档没有示例,因此我不确定它应该如何使用。

1 个答案:

答案 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 ,为什么会发生骚扰?

进一步更新,似乎输入字符串只能包含字母数字,集合;中的字符和空格 - 在小数位后 - 即你不能将时区信息内容与除了我之外的任何字符分开如上所列(它并非详尽无遗,没有时间对所有人进行测试!)