我感到惊讶的是,boost::date_time似乎可以编写它无法读取的日期/时间字符串。
考虑以下示例代码:
#include <boost/date_time/local_time/local_time.hpp>
#include <iostream>
#include <locale>
class PointTime : public boost::local_time::local_date_time {
typedef boost::local_time::local_time_input_facet input_facet_t;
typedef boost::local_time::local_time_facet output_face_t;
public:
static input_facet_t const s_input_facet;
static output_face_t const s_output_facet;
static std::locale const s_input_locale;
static std::locale const s_output_locale;
public:
PointTime(std::string const& str);
};
PointTime::input_facet_t const PointTime::s_input_facet("%Y-%m-%dT%H:%M:%S%q", 1);
PointTime::output_face_t const PointTime::s_output_facet("%Y-%m-%dT%H:%M:%S%q",
boost::local_time::local_time_facet::period_formatter_type(),
boost::local_time::local_time_facet::special_values_formatter_type(),
boost::local_time::local_time_facet::date_gen_formatter_type(),
1);
std::locale const PointTime::s_input_locale(std::locale::classic(), &PointTime::s_input_facet);
std::locale const PointTime::s_output_locale(std::locale::classic(), &PointTime::s_output_facet);
PointTime::PointTime(std::string const& str) : boost::local_time::local_date_time(boost::local_time::not_a_date_time)
{
std::istringstream is(str);
is.imbue(s_input_locale);
is >> *this;
std::string s;
is >> s;
std::cout << "Left after parsing: \"" << s << "\"." << std::endl;
}
int main()
{
std::string ts("2005-10-15T13:12:11-0700");
std::cout << "ts = " << ts << std::endl;
try
{
PointTime t(ts);
std::cout.imbue(PointTime::s_output_locale);
std::cout << "t = " << t << std::endl;
}
catch (boost::bad_lexical_cast const& error)
{
std::cout << error.what() << std::endl;
}
return 0;
}
这将输出:
ts=2005-10-15T13:12:11-0700
解析后左:“-0700”。
t=2005-10-15T13:12:11Z
我理解它为什么这样做:%q格式被记录为“仅输出”,但我找不到实际读回此字符串的方法?!我应该怎么做?
不幸的是,是的,这是目前的一个限制
添加了一些新标志,并覆盖了其他标志。输入系统仅支持特定标志,因此,并非所有用于输出的标志都与输入一起使用(我们目前正在努力纠正这种情况)。
同时,您也许能够利用 Boost Locale 的输入/输出功能:http://www.boost.org/doc/libs/1_55_0/libs/locale/doc/html/group__manipulators.html
最后,我使用了一个定制的方法来读回这些字符串。
我使用从< code > boost::POSIX _ time::ptime 派生的类来节省存储空间(超过从< code > boost::local _ time::local _ date _ time 派生的类),因为我不再使用boost-date-time的时区支持。
然而,当以字符串形式打印日期时,我希望它以“Z”结束,以表明它是祖鲁时间(UTC,GMT)而不是当地时间。我通过使用带有以“Z”结尾的格式字符串的输出方面实现了这一点。
PointTime
类定义了一些(输入和输出)方面(即ISOInputFacet
,ExtendedISOInputFacet
和那些称为LLInputFacet
的混合体,因为Linden Lab认为这是ISO标准并将其用于SecondLife(tm),呃。同样,ISOOutputFacet
,ExtendedISOOutputFacet
和LLOutputFacet
。
该类实例化了六个方面中每一个的静态版本,因为我不想每次创建、读取或写入PointTime时都为一个方面调用new/ete。
这个函数的主要技巧是:
std::istream& operator>>(std::istream& is, PointTime& point_time)
{
is >> static_cast<boost::posix_time::ptime&>(point_time);
std::locale loc(is.getloc());
if (std::has_facet<PointTime::InputFacet>(loc))
{
std::use_facet<PointTime::InputFacet>(loc).parse_timezone(is, point_time);
}
return is;
}
它窥视正在使用的输入方面,当它是从<code>PointTime::InputFacet</code>派生的输入方面时,它调用成员函数来解析可能的剩余时区。
下面给出了我编写的测试代码。也许它可以作为其他人的示例代码。
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <iostream>
#include <locale>
#include <cassert>
class TZSignOrZ;
class PointTime : public boost::posix_time::ptime {
public:
struct InputFacet : public boost::posix_time::time_input_facet {
InputFacet(char const* format, size_t ref_arg) : boost::posix_time::time_input_facet(format, ref_arg) { }
static void parse_iso_timezone(std::istream& is, PointTime& point_time, bool colon);
static void parse_hours_and_minutes(std::istream& is, PointTime& point_time, TZSignOrZ const& sign, bool colon);
virtual void parse_timezone(std::istream& is, PointTime& point_time) const = 0;
};
struct ISOInputFacet : public InputFacet {
ISOInputFacet(size_t ref_arg = 0) : InputFacet("%Y%m%dT%H%M%S%F", ref_arg) { }
/*virtual*/ void parse_timezone(std::istream& is, PointTime& point_time) const;
};
struct ExtendedISOInputFacet : public InputFacet {
ExtendedISOInputFacet(size_t ref_arg = 0) : InputFacet("%Y-%m-%d %H:%M:%S%F", ref_arg) { }
/*virtual*/ void parse_timezone(std::istream& is, PointTime& point_time) const;
};
struct LLInputFacet : public InputFacet {
LLInputFacet(size_t ref_arg = 0) : InputFacet("%Y-%m-%dT%H:%M:%S%F", ref_arg) { }
/*virtual*/ void parse_timezone(std::istream& is, PointTime& point_time) const;
};
struct OutputFacet : public boost::posix_time::time_facet {
OutputFacet(char const* format, size_t ref_arg) :
boost::posix_time::time_facet(
format, boost::posix_time::time_facet::period_formatter_type(),
boost::posix_time::time_facet::special_values_formatter_type(),
boost::posix_time::time_facet::date_gen_formatter_type(), ref_arg) { }
};
struct ISOOutputFacet : public OutputFacet {
ISOOutputFacet(size_t ref_arg = 0) : OutputFacet("%Y%m%dT%H%M%S%FZ", ref_arg) { }
};
struct ExtendedISOOutputFacet : public OutputFacet {
ExtendedISOOutputFacet(size_t ref_arg = 0) : OutputFacet("%Y-%m-%d %H:%M:%S%FZ", ref_arg) { }
};
struct LLOutputFacet : public OutputFacet {
LLOutputFacet(size_t ref_arg = 0) : OutputFacet("%Y-%m-%dT%H:%M:%S%FZ", ref_arg) { }
};
static ISOInputFacet s_iso_input_facet;
static ExtendedISOInputFacet s_extended_iso_input_facet;
static LLInputFacet s_ll_input_facet;
static ISOOutputFacet s_iso_output_facet;
static ExtendedISOOutputFacet s_extended_iso_output_facet;
static LLOutputFacet s_ll_output_facet;
public:
PointTime(void) { }
PointTime(std::string const& str, InputFacet const& input_facet = s_extended_iso_input_facet);
friend std::istream& operator>>(std::istream& os, PointTime& point_time);
};
PointTime::ISOInputFacet PointTime::s_iso_input_facet(1);
PointTime::ExtendedISOInputFacet PointTime::s_extended_iso_input_facet(1);
PointTime::LLInputFacet PointTime::s_ll_input_facet(1);
PointTime::ISOOutputFacet PointTime::s_iso_output_facet(1);
PointTime::ExtendedISOOutputFacet PointTime::s_extended_iso_output_facet(1);
PointTime::LLOutputFacet PointTime::s_ll_output_facet(1);
PointTime::PointTime(std::string const& str, InputFacet const& input_facet) : boost::posix_time::ptime(boost::posix_time::not_a_date_time)
{
std::istringstream is(str);
is.imbue(std::locale(std::locale::classic(), &input_facet));
is >> *this;
}
std::istream& operator>>(std::istream& is, PointTime& point_time)
{
is >> static_cast<boost::posix_time::ptime&>(point_time);
std::locale loc(is.getloc());
if (std::has_facet<PointTime::InputFacet>(loc))
{
std::use_facet<PointTime::InputFacet>(loc).parse_timezone(is, point_time);
}
return is;
}
struct TZSignOrZ {
char c;
friend std::istream& operator>>(std::istream& is, TZSignOrZ& sign)
{
sign.c = is.get();
if (!is.good() || (sign.c != 'Z' && sign.c != '+' && sign.c != '-'))
{
if (!is.fail())
{
is.putback(sign.c);
}
throw std::runtime_error("Failed to read TZSignOrZ: first character after date-time is not a 'Z' or a sign.");
}
return is;
}
bool is_utc(void) const { return c == 'Z'; }
bool is_negative(void) const { return c == '-'; }
};
struct TZColon {
friend std::istream& operator>>(std::istream& is, TZColon& colon)
{
char c = is.get();
if (!is.good() || c != ':')
throw std::runtime_error("Failed to read TZColon: expected a colon between hours and minutes in time zone of date-time.");
return is;
}
};
struct TZTwoDigits {
unsigned char val;
friend std::istream& operator>>(std::istream& is, TZTwoDigits& digits)
{
char c1, c2;
is >> std::noskipws >> c1 >> c2;
if (!is.good() || !std::isdigit(c1) || !std::isdigit(c2))
throw std::runtime_error("Failed to read TZTwoDigits: expected two digits for hours or minutes part in time zone of data-time.");
digits.val = c2 - '0' + 10 * (c1 - '0');
return is;
}
};
void PointTime::InputFacet::parse_hours_and_minutes(std::istream& is, PointTime& point_time, TZSignOrZ const& sign, bool colon)
{
TZTwoDigits hours, minutes;
is >> hours;
if (colon)
{
TZColon colon;
is >> colon;
}
is >> minutes;
boost::posix_time::time_duration duration(hours.val, minutes.val, 0, 0);
if (sign.is_negative())
point_time += duration;
else
point_time -= duration;
}
void PointTime::InputFacet::parse_iso_timezone(std::istream& is, PointTime& point_time, bool colon)
{
if (!is.good())
return; // Don't throw when the input stream is already bad.
TZSignOrZ sign;
try
{
is >> sign;
}
catch (std::runtime_error const&)
{
// It is actually allowed to have no time zone.
return;
}
parse_hours_and_minutes(is, point_time, sign, colon);
}
void PointTime::ISOInputFacet::parse_timezone(std::istream& is, PointTime& point_time) const
{
parse_iso_timezone(is, point_time, false);
}
void PointTime::ExtendedISOInputFacet::parse_timezone(std::istream& is, PointTime& point_time) const
{
parse_iso_timezone(is, point_time, true);
}
void PointTime::LLInputFacet::parse_timezone(std::istream& is, PointTime& point_time) const
{
if (!is.good())
return; // Don't throw when the input stream is already bad.
TZSignOrZ sign;
is >> sign;
if (sign.is_utc())
return;
parse_hours_and_minutes(is, point_time, sign, false);
}
int main()
{
std::string test_strings[] = {
"2014-09-10T00:12:34+0230",
"2014-09-10T00:12:34.000567+0230",
"2014-09-10T00:12:34.567+0230",
"2014-09-10T21:32:34-0230",
"2014-09-10T21:32:34.000567-0230",
"2014-09-10T21:32:34.567-0230",
"2014-09-10 00:12:34+02:30",
"2014-09-10 00:12:34.000567+02:30",
"2014-09-10 00:12:34.567+02:30",
"2014-09-10 21:32:34-02:30",
"2014-09-10 21:32:34.000567-02:30",
"2014-09-10 21:32:34.567-02:30",
"2014-09-10 00:12:34 hello!",
"2014-09-10 00:12:34.000567***",
"2014-09-10 00:12:34.567 hello!",
"2014-09-10T00:12:34 +0230",
"2014-09-10T00:12:34+ 0230",
"2014-09-10T00:12:34+02 30",
"2014-09-10T00:12:34 +02:30",
"2014-09-10T00:12:34+ 02:30",
"2014-09-10T00:12:34+02: 30",
"2014-09-10T00:12:34+02 :30"
};
int const n = sizeof(test_strings) / sizeof(test_strings[0]);
PointTime::InputFacet const* facets[] = {
&PointTime::s_ll_input_facet,
&PointTime::s_extended_iso_input_facet
};
std::cout << std::left << std::setw(32) << "INPUT" << " " <<
std::setw(40) << "LL input format" << " " <<
std::setw(40) << "Extended ISO input format" << std::endl;
for (int i = 0 ; i < n ; ++i)
{
std::cout << std::left << std::setw(32) << test_strings[i];
for (int j = 0; j < 2; ++j)
{
try
{
PointTime t;
std::istringstream is(test_strings[i]);
is.imbue(std::locale(std::locale::classic(), facets[j]));
is >> t;
std::string leftover;
is >> std::noskipws;
std::getline(is, leftover);
std::ostringstream oss;
oss.imbue(std::locale(std::locale::classic(), &PointTime::s_extended_iso_output_facet));
oss << t;
if (!leftover.empty())
{
oss << " [\"" << leftover << "\"]";
}
std::cout << " -- " << std::setw(40) << oss.str();
}
catch (boost::bad_lexical_cast const& error)
{
std::cout << " -- " << std::setw(40) << "invalid date-time";
}
catch (std::runtime_error const& error)
{
std::cout << " -- " << std::setw(40) << "invalid TZ";
}
}
std::cout << std::endl;
}
return 0;
}
该程序的输出为:
INPUT LL input format Extended ISO input format
2014-09-10T00:12:34+0230 -- 2014-09-09 21:42:34Z -- invalid TZ
2014-09-10T00:12:34.000567+0230 -- 2014-09-09 21:42:34.000567Z -- invalid TZ
2014-09-10T00:12:34.567+0230 -- 2014-09-09 21:42:34.567000Z -- invalid TZ
2014-09-10T21:32:34-0230 -- 2014-09-11 00:02:34Z -- invalid TZ
2014-09-10T21:32:34.000567-0230 -- 2014-09-11 00:02:34.000567Z -- invalid TZ
2014-09-10T21:32:34.567-0230 -- 2014-09-11 00:02:34.567000Z -- invalid TZ
2014-09-10 00:12:34+02:30 -- invalid TZ -- 2014-09-09 21:42:34Z
2014-09-10 00:12:34.000567+02:30 -- invalid TZ -- 2014-09-09 21:42:34.000567Z
2014-09-10 00:12:34.567+02:30 -- invalid TZ -- 2014-09-09 21:42:34.567000Z
2014-09-10 21:32:34-02:30 -- invalid TZ -- 2014-09-11 00:02:34Z
2014-09-10 21:32:34.000567-02:30 -- invalid TZ -- 2014-09-11 00:02:34.000567Z
2014-09-10 21:32:34.567-02:30 -- invalid TZ -- 2014-09-11 00:02:34.567000Z
2014-09-10 00:12:34 hello! -- invalid TZ -- 2014-09-10 00:12:34Z [" hello!"]
2014-09-10 00:12:34.000567*** -- invalid TZ -- 2014-09-10 00:12:34.000567Z ["***"]
2014-09-10 00:12:34.567 hello! -- invalid TZ -- 2014-09-10 00:12:34.567000Z [" hello!"]
2014-09-10T00:12:34 +0230 -- invalid TZ -- 2014-09-10 00:12:34Z [" +0230"]
2014-09-10T00:12:34+ 0230 -- invalid TZ -- invalid TZ
2014-09-10T00:12:34+02 30 -- invalid TZ -- invalid TZ
2014-09-10T00:12:34 +02:30 -- invalid TZ -- 2014-09-10 00:12:34Z [" +02:30"]
2014-09-10T00:12:34+ 02:30 -- invalid TZ -- invalid TZ
2014-09-10T00:12:34+02: 30 -- invalid TZ -- invalid TZ
2014-09-10T00:12:34+02 :30 -- invalid TZ -- invalid TZ
我有一个这样的文件: [data.json] 如何通过解析此文件创建粒子向量。据我所知,我需要使用boop读取文件并将字符串(行)读入向量,然后解析向量的内容。 类粒子是这样的: 该类中省略了其他用于 get/set 的方法。 基本上,我想帮助创建一个
问题内容: HTTP服务器向我发送JSON响应(字符串),如下所示: 我想将此“远程文件夹的树”与本地文件夹树(例如,包含本地文件位置的字符串向量)进行比较,因此我想在(string,vector(map(string ,string)))(我不知道是否可行)。 我正在开发一种工具来在本地文件夹和远程文件夹之间同步文件,因此我正在使用boost列出本地文件夹,并且我想将本地列表与远程列表(JSON
一个HTTP服务器发送给我一个JSON响应(一个字符串),如下所示: 我想将这个“远程文件夹的树”与本地文件夹树(例如包含我的本地文件的位置的字符串向量)进行比较,所以我想在(string,vector ( map(string,string))(我不知道这是否可能)的地图上转换这个JSON。 我正在开发一个工具来同步本地和远程文件夹之间的文件,因此我正在使用boost列出本地文件夹,并且我想将本
问题内容: 我目前正在尝试使用boost-asio的套接字API通过网络将一些JSON数据从客户端传输到服务器。我的客户基本上是这样做的: 在服务器端,我可以选择各种功能。我想使用JsonCpp解析接收到的数据。在研究JsonCpp API(http://jsoncpp.sourceforge.net/class_json_1_1_reader.html)时,我发现Reader可以在char数组或
本文向大家介绍使用boost读取XML文件详细介绍,包括了使用boost读取XML文件详细介绍的使用技巧和注意事项,需要的朋友参考一下 boost读取XML文件 boost中提供了对配置文件读取的支持,它就是:property_tree。 basic_ptree 是property_tree的核心基础。其接口像std::list。可以执行很多基本的元素操作,比如使用begin()、end(
ISO 8601将持续时间格式声明为。例如,表示“3年、半个月和3分钟”。 有各种方法可以转换成unixtime/chrono::duration/whatever,但是我找到的所有解决方案都是用秒为单位的平均月和年持续时间,按照标准这是不正确的。相反,它应该取决于日期,例如< code>01 Feb P1M应该是< code>01 Mar ( 28天),而< code>01 Mar P1M应该是