我需要将时间从UTC转换为用户选择的时区。 我还必须从该时区的用户输入转换以 UTC 格式存储。
目前时区以奥尔森格式定义("美国/洛杉矶")。
使用 timegm 的 Linux 上很容易找到解决方案,但我找不到在 Windows 上做完全相同事情的跨平台解决方案(或任何解决方案)。
我不能使用Boost.Date_Time (http://www.boost.org/doc/libs/1_57_0/doc/html/date_time.html),因为它不支持历史时区更改,例如多年来 DST 期间的变化。 有人显然在几年前提交了补丁,但似乎没有被接受。
唯一可能的其他解决方案是使用来自以下方面的数据和代码: https://www.iana.org/time-zones
有没有人尝试过这个,或者你有更好的主意吗?
这是一个跨平台的开源 C++11/C++14 时区库,它包装了 IANA 时区数据库,包括所有历史数据。 IANA 数据库是当前维护的奥尔森数据库。
此库中的一个例子是:
#include "tz.h"
#include <iostream>
int
main()
{
using namespace std::chrono_literals;
using namespace date;
auto departure = make_zoned("America/New_York",
local_days{dec/30/1978} + 12h + 1min);
auto flight_length = 14h + 44min;
auto arrival = make_zoned("Asia/Tehran",
departure.get_sys_time() + flight_length);
std::cout << "departure NYC time: " << departure << 'n';
std::cout << "flight time is " << make_time(flight_length) << 'n';
std::cout << "arrival Tehran time: " << arrival << 'n';
}
其中输出:
departure NYC time: 1978-12-30 12:01:00 EST
flight time is 14:44
arrival Tehran time: 1978-12-31 11:45:00 IRST
注意日期:1978 年 12 月。 这在历史上是准确的(就时区处理而言)。 该论文继续演示了由于德黑兰时区的变化,第二天同一航班的到达时间如何不同。
上面的示例不处理闰秒。 但是,如果您确实想要处理闰秒,该库可以通过少量的额外工作来处理它:
#include "tz.h"
#include <iostream>
int
main()
{
using namespace std::chrono_literals;
using namespace date;
auto departure = make_zoned("America/New_York",
local_days{dec/31/1978} + 12h + 1min);
auto departure_utc = to_utc_time(departure.get_sys_time());
auto flight_length = 14h + 44min;
auto arrival = make_zoned("Asia/Tehran",
to_sys_time(departure_utc + flight_length));
std::cout << "departure NYC time: " << departure << 'n';
std::cout << "flight time is " << make_time(flight_length) << 'n';
std::cout << "arrival Tehran time: " << arrival << 'n';
}
departure NYC time: 1978-12-31 12:01:00 EST
flight time is 14:44
arrival Tehran time: 1979-01-01 11:14:59 IRST
这在以下位置都有详细描述:
http://howardhinnant.github.io/date/tz.html
并可在以下网址免费获得:
https://github.com/HowardHinnant/date