“2012-06-01 16:45:34 EDT”
我试图用folloiwng创建一个local_time_input_facet:
“%Y-%m-%d%H:%M:%S%Z”
始终未设置local_date_time对象的区域指针.阅读文档令人困惑:
%Z *!
Full time zone name (output only). This flag is ignored when using the time_facet with a ptime.
“EDT”//东部夏令时
有没有人这样做过?
更新:我已更新代码以更好地说明问题:
using namespace std; using namespace boost::local_time; int main() { stringstream ss; // Set up the input datetime format. local_time_input_facet *input_facet = new local_time_input_facet("%Y-%m-%d %H:%M:%S %ZP"); ss.imbue(std::locale(ss.getloc(),input_facet)); local_date_time ldt(not_a_date_time),ldt1(not_a_date_time); // Read a time into ldt ss.str("2012-06-01 17:45:34 EDT"); ss >> ldt; ss.str("2012-06-01 17:45:34 CDT"); ss >> ldt1; std::cerr << (ldt - ldt1).total_seconds() << std::endl; // Write the time to stdout. cout << "Full Time:\t" << ldt.to_string() << endl; cout << "Local time:\t" << ldt.local_time() << endl; cout << "Time zone:\t" << ldt.zone_as_posix_string() << endl; cout << "Zone abbrev:\t" << ldt.zone_abbrev() << endl; cout << "Zone offset:\t" << ldt.zone_abbrev(true) << endl; cout << "Full Time:\t" << ldt1.to_string() << endl; cout << "Local time:\t" << ldt1.local_time() << endl; cout << "Time zone:\t" << ldt1.zone_as_posix_string() << endl; cout << "Zone abbrev:\t" << ldt1.zone_abbrev() << endl; cout << "Zone offset:\t" << ldt1.zone_abbrev(true) << endl; return 0; }
OUTPUT:
0 Full Time: 2012-Jun-01 17:45:34 EDT Local time: 2012-Jun-01 17:45:34 Time zone: EDT+00 Zone abbrev: EDT Zone offset: +0000 Full Time: 2012-Jun-01 17:45:34 CDT Local time: 2012-Jun-01 17:45:34 Time zone: CDT+00 Zone abbrev: CDT Zone offset: +0000
解决方法
根据boost的文档:http://www.boost.org/doc/libs/1_57_0/doc/html/date_time/date_time_io.html#date_time.format_flags
%Z是:
Full time zone name (output only).
它还说%ZP:
Posix time zone string (available to both input and output).
因此,您需要将%Z更改为%ZP.现在你的时间戳将解析.但是,您会注意到不会设置区域偏移.
Posix时区字符串
对于Posix时区字符串,您至少需要指定区域缩写和UTC的偏移量,例如: EST-5.
完整的Posix时区字符串格式为:
"std offset dst [offset],start[/time],end[/time]"
以下是EST和PST的完整Posix时区字符串的一些示例:
EST-5EDT,M3.2.0,M11.1.0 PST-8PDT,M4.1.0,M10.1.0
其中包含有关夏令时何时生效的信息.
但是,您可以在您的情况下使用EDT-4,具体取决于您正在使用它.
应该注意的是,就像Posix时区一样简单,它们受到限制,因为它们不考虑时区规则的历史变化.我认为最好不要首先避免使用时区.
如果我无法控制输入格式怎么办?
正如评论中提到的OP,偏移量未列在其输入时间戳中.一种解决方案是从输入时间戳的末尾读取区域缩写(例如“EDT”),并根据已知区域缩写的映射进行检查:
std::map<std::string,std::string> zone_map; zone_map["EST"] = "EST-5EDT,M10.5.0"; // Eastern Standard Time zone_map["EDT"] = zone_map["EST"]; // Eastern Daylight Time zone_map["PST"] = "PST-8PDT,M10.1.0"; // Pacific Standard Time zone_map["PDT"] = zone_map["PST"]; // Pacific Daylight Time // ...
(请注意,上面的DST区域应与标准时区相同.)
您可能只需存储简单的UTC偏移即可:
zone_map["EST"] = "EST-5"; // Eastern Standard Time zone_map["EDT"] = "EDT-4"; // Eastern Daylight Time // ...
工作实例
这是一个使用内置时区数据库的示例:
#include <map> #include <string> #include <sstream> #include <iostream> #include <boost/date_time/local_time/local_time.hpp> using namespace boost::local_time; int main() { // A little database of time zones. std::map<std::string,std::string> zone_map; zone_map["EST"] = "EST-5EDT,M10.5.0"; // Eastern Standard Time zone_map["EDT"] = zone_map["EST"]; // Eastern Daylight Time zone_map["PST"] = "PST-8PDT,M10.1.0"; // Pacific Standard Time zone_map["PDT"] = zone_map["PST"]; // Pacific Daylight Time // ... // This is our input timestamp. std::string timestamp = "2012-06-01 16:45:34 EDT"; // Replace time zone abbrev with full Posix time zone. const size_t abbrev_pos = timestamp.find_last_of(' ') + 1; const std::string abbrev = timestamp.substr(abbrev_pos); timestamp.replace(abbrev_pos,std::string::npos,zone_map[abbrev]); std::cout << "Time stamp with full timezone: " << timestamp << std::endl; // Set up the input datetime format. local_time_input_facet *input_facet = new local_time_input_facet("%Y-%m-%d %H:%M:%S %ZP"); std::stringstream ss; ss.imbue(std::locale(ss.getloc(),input_facet)); // This is our output date time. local_date_time ldt(not_a_date_time); // Read the timestamp into ldt. ss.str(timestamp); ss >> ldt; // Write the time to stdout. std::cout << "Full Time:\t" << ldt.to_string() << std::endl << "Local time:\t" << ldt.local_time() << std::endl << "Time zone:\t" << ldt.zone_as_posix_string() << std::endl << "Zone abbrev:\t" << ldt.zone_abbrev() << std::endl << "Zone offset:\t" << ldt.zone_abbrev(true) << std::endl; return 0; }
这输出:
Time stamp with full timezone: 2012-06-01 16:45:34 EST-5EDT,M10.5.0 Full Time: 2012-Jun-01 16:45:34 EDT Local time: 2012-Jun-01 16:45:34 Time zone: EST-05EDT+01,M4.1.0/02:00,M10.5.0/02:00 Zone abbrev: EDT Zone offset: -0400