- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在使用 %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);
}
当使用输入字符串 16:03:38.539000
打印 et_time
或 cet_time
时,我得到了
16:03:38.539000 UTC
我很期待
et_time
与 UTC
不同,因为我构建它时提供了 et_tz
时区对象。cet_time
处于不同的时区,因为我使用 local_time_in
构建它并提供 cet_tz
时区对象。我做错了什么?
最佳答案
我不知道 ec2cet
的 boost 实现有什么问题.但是我可以展示如何用这个 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 行:只需将格式字符串写在一处即可。 “%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 行:创建一个 zoned_time<microseconds>
使用“美国/纽约”time_zone
和 local_time tp
.你可以想到一个 zoned_time
作为简单的 pair<time_zone, local_time>
尽管细节比这稍微复杂一些。
第 11 行:创建一个 zoned_time<microseconds>
来自 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 而不是“America/New_York”,这也是第 6 行的单行更改(将类型设为 tp
sys_time<microseconds>
而不是 local_time<microseconds>
)。
关于c++ - `boost::local_time::date_time` 来自 `std::string`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41536747/
我需要读取 ISO 扩展格式的时间,并将其转换为 UTC 时间,就像 Javascript 的 Date 对象所做的那样: new Date("2014-12-19T15:53:14.533+01:0
我想转换一个 boost::posix_time::ptime到 boost::local_time::local_date_time使用没有夏令时的时区仅由它与 UTC 的偏移量指定。我正在使用 b
#include #include "boost/date_time/posix_time/posix_time.hpp" int main(int argc, char** argv) { b
如何从 tm 时间结构创建一个 boost::local_time::local_date_time 对象? 最佳答案 有点痛苦,但看起来你必须通过 posix_time::ptime: using
我正在使用 %Y-%m-%d %H:%M:%S%f 格式的日期/时间字符串。 我想设计一个函数,它接受 America/New_York 时区的日期/时间字符串,并返回 Europe/Paris 时区
我在带有回调的异步模式下使用 ALSA (snd_async_add_pcm_handler())。每个 ALSA 的回调都是从 SIGIO 信号处理程序调用的。每个回调调用我的函数getCurren
我是一名优秀的程序员,十分优秀!