`boost::local_time::date_time` from `std::string`
`boost::local_time::date_time` from `std::string`
我正在使用%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
处于不同的时区,因为我使用local_time_in
构建它并提供cet_tz
时区对象。
我做错了什么?
我不知道ec2cet
的提升实现有什么问题。 但是,我可以很容易地展示如何使用这个免费的开源库来做到这一点。 首先是代码,然后是逐行说明:
#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 行:只需将格式字符串写在一个地方。 "%F %T"等效于"%Y-%m-%d %H:%M:%S",您也可以使用它。(我很懒)。
第 5 行:这个库会解析出任何流,所以我们需要将输入字符串date_time_str
转换为流 (in
)。
第 6 行:您说已知输入字符串表示"America/New_York"中的本地日期/时间。local_time<microseconds>
类型是一个chrono::time_point
,它可以以微秒精度表示任何时区的本地时间。 这个(tp
)的一个实例就是我们要解析date_time_str
的。
第 7 行:解析为tp
。
第 8-9 行:检查是否存在解析错误。
第 10 行:使用"美国/New_York"time_zone
和local_time tp
创建zoned_time<microseconds>
。 您可以将zoned_time
简单地视为pair<time_zone, local_time>
尽管细节比这稍微复杂一些。
第 11 行:从"欧洲/巴黎"和zoned_time et_time
time_zone
创建一个zoned_time<microseconds>
。 这会将一个本地时间转换为另一个本地时间,从而等同于过程中的 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 而不是"America/New_York",那也是第 6 行的单行更改(使类型为tp
sys_time<microseconds>
而不是local_time<microseconds>
)。
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- C STD :: Local Time Daylight节省时间规则(DST)欧洲与美国人
- 正在使用 std::time 和 std::srand 有效代码
- 如何设计一个简单的 std::string-to-boost::p osix_time::p time 解析库
- Windows threads (c run-time, pthreads, std::thread)
- 使用STD和c++从set with constant time中删除一个值
- 写一个std::string到可比的*time*解析器,这可能会失败
- Std::random_shuffle即使调用一次srand(time(0))也会产生相同的结果
- std::vector:<int>:clear, constant time?