我正在尝试使用 Boost 的日期时间库以自定义格式解析日期/时间字符串。我尝试使用的格式很不寻常,因为它包含 Posix 时区描述字符串。 docs图书馆clearly state有一个标志 (%ZP
) 可用于处理 Posix 时区字符串的输入和输出。我试图解析的值来自网络浏览器,而不是编写 JS 来执行区域字符串中指定的转换,然后以 UTC 发送到服务器,我宁愿只在服务器端进行(因为Boost 应该很容易做到这一点)。显然,如果它有效,我不会在这里发帖。此代码抛出一个 boost::bad_lexical_cast
,其值为“source type value could not be interpreted as target”。
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
标志的文档没有示例,所以我不确定应该如何使用它。
最佳答案
我认为您的格式字符串应该如下所示:%Y-%m-%dT%H:%M:%s *;%ZP
%s *
将匹配秒和小数秒。通过此更改,上面的代码运行了,但奇怪的是,我得到的输出是:
1989-Nov-09 15:30:42.005000 ST
不确定为什么它说的是 ST
而不是 PST
,但是时区信息确实得到了正确的解析,如果您将日期更改为例如 Nov-01,那么它将报告 PDT
。
编辑:时区对象的描述是here .
好吧,从搞乱这个开始,解析错误似乎是由 ;
的存在引起的,将它从原始字符串中删除,这样它就变成了:
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
这告诉我这确实是在尊重字符串中嵌入的时区信息...所以有趣的问题是如果有 ;
为什么它会呕吐?
进一步更新,似乎输入字符串只能包含字母数字、.:-,
集合中的字符和空格 - 在小数位之后 - 即你不能将时区信息与任何内容分开我上面列出的字符以外的字符(它并不详尽,没有时间测试所有字符!)
关于c++ - 使用带有时区字符串的 Boost 日期时间库解析失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4800385/