我正在处理%Y-%m-%d %H:%M:%S%f
格式的日期/时间字符串。
我想设计一个函数,该函数在America/New_York
时区中获取日期/时间字符串,并在Europe/Paris
时区中返回日期/时间字符串。
我想出了以下
std::string ec2cet(const std::string &date_time_str)
{
using namespace boost::posix_time;
using namespace boost::gregorian;
using namespace boost::local_time;
tz_database tz_db;
time_zone_ptr et_tz = tz_db.time_zone_from_region("America/New_York");
time_zone_ptr cet_tz = tz_db.time_zone_from_region("Europe/Paris");
ptime absolute_time = time_from_string(date_time_str);
local_date_time ec_time(absolute_time, et_tz);
local_date_time cet_time = et_time.local_time_in(cet_tz);
return to_simple_string(cet_time);
}
使用输入字符串et_time
打印cet_time
或16:03:38.539000
时,我得到了
16:03:38.539000 UTC
我在期待
et_time
与UTC
不同,因为我构建了它,提供了et_tz
时区对象。cet_time
构建{li> local_time_in
并提供cet_tz
时区对象时,np.array
位于不同的时区。我做错了什么?
答案 0 :(得分:2)
我不知道ec2cet
的加速实施有什么问题。但是我可以很容易地用这个free, open source library来说明如何做到这一点。首先是代码,然后是逐行说明:
#include "tz.h"
#include <iostream>
#include <sstream>
#include <string>
std::string
ec2cet(const std::string& date_time_str)
{
using namespace std; // 1
using namespace std::chrono; // 2
using namespace date; // 3
constexpr auto fmt = "%F %T"; // 4
istringstream in{date_time_str}; // 5
local_time<microseconds> tp; // 6
in >> parse(fmt, tp); // 7
if (in.fail()) // 8
return std::string{}; // 9
auto et_time = make_zoned("America/New_York", tp); // 10
auto cet_time = make_zoned("Europe/Paris", et_time); // 11
cout << "et_time = " << et_time << '\n'; // 12
cout << "cet_time = " << cet_time << '\n'; // 13
return format(fmt, cet_time); // 14
}
第1-3行只是把所有东西都带到了当地空间,所以事情并不那么冗长。
第4行:只需在一个地方写下格式字符串即可。 &#34;%F%T&#34;相当于&#34;%Y-%m-%d%H:%M:%S&#34;你也可以使用它。 (我懒惰)。
第5行:此库将解析出任何流,因此我们需要将输入字符串date_time_str
转换为流(in
)。
第6行:您说已知输入字符串代表&#34; America / New_York&#34;中的本地日期/时间。类型local_time<microseconds>
是chrono::time_point
,可以表示任何时区的本地时间到微秒的精度。这个(tp
)的一个实例是我们将date_time_str
解析为。{/ p>
第7行:解析为tp
。
第8-9行:检查解析错误。
第10行:使用&#34; America / New_York&#34;创建zoned_time<microseconds>
time_zone
和local_time tp
。您可以将zoned_time
简单地视为pair<time_zone, local_time>
,但细节稍微复杂一些。
第11行:从zoned_time<microseconds>
&#34;欧洲/巴黎&#34;创建time_zone
和zoned_time et_time
。这会将一个本地时间转换为另一个本地时间,在此过程中等同它们的UTC等价物。
第12-13行:输出这些中间结果(et_time
和cet_time
以进行调试)。
第14行:将cet_time
格式化为所需的std::string
并将其返回。
使用以下驱动程序运行它:
int
main()
{
auto s = ec2cet("2017-01-08 16:03:38.539000");
std::cout << "ec2cet = " << s << '\n';
}
输出:
et_time = 2017-01-08 16:03:38.539000 EST
cet_time = 2017-01-08 22:03:38.539000 CET
ec2cet = 2017-01-08 22:03:38.539000
此程序会跟踪当前的IANA时区数据库,并将正确遵循IANA数据库完整历史记录的时区规则,这两个时区自1800年代后期开始。
如果microseconds
精度不是你想要的,你可以改变它(在第6行的一个地方)。如果输入字符串应该是UTC而不是&#34; America / New_York&#34;,那么这也是第6行的单行更改(使tp
sys_time<microseconds>
的类型而不是{{ 1}})。