C++ 跨平台C++;:使用历史数据转换为UTC/本地时间

C++ 跨平台C++;:使用历史数据转换为UTC/本地时间,c++,windows,timezone,utc,C++,Windows,Timezone,Utc,我需要将时间从UTC转换为用户选择的时区。我还必须将该时区的用户输入转换为UTC存储 目前,时区是以奥尔森格式(“美国/洛杉矶”)定义的 有了timegm,Linux上的解决方案很容易,但我找不到一个跨平台的解决方案(或任何解决方案)在Windows上做完全相同的事情 我不能使用Boost.Date_Time(),因为它不支持历史时区更改,例如多年来不断变化的DST时段。显然有人在几年前提交了补丁,但似乎没有被接受 唯一可行的其他解决方案是使用以下数据和代码: 有人试过这个吗?或者你有更好的主意

我需要将时间从UTC转换为用户选择的时区。我还必须将该时区的用户输入转换为UTC存储

目前,时区是以奥尔森格式(“美国/洛杉矶”)定义的

有了timegm,Linux上的解决方案很容易,但我找不到一个跨平台的解决方案(或任何解决方案)在Windows上做完全相同的事情

我不能使用Boost.Date_Time(),因为它不支持历史时区更改,例如多年来不断变化的DST时段。显然有人在几年前提交了补丁,但似乎没有被接受

唯一可行的其他解决方案是使用以下数据和代码:

有人试过这个吗?或者你有更好的主意吗?

可以包装所有的历史数据。IANA数据库是目前维护的Olson数据库

该库中的一个示例是:

#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';
}
注日期: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
#包括“tz.h”
#包括
int
main()
{
使用名称空间std::chrono_文本;
使用名称空间日期;
自动出发=进行分区(“美国/纽约”,
当地日{1978年12月31日}+12小时+1分钟);
自动出发协调世界时=到协调世界时(出发。获取系统时间());
自动飞行长度=14h+44min;
自动到达=进行分区(“亚洲/德黑兰”,
至系统时间(起飞时间+航班长度);

std::你能考虑一下吗?它有相当好的时区支持。我放弃了它,因为“ICU不关心闰秒或历史行为”。但我会仔细看一看。这是关于UTC/GMT术语的。与Boost不同,这里确实有丰富的IANA tzdata。看起来ICU可以工作。我先看了Boost,他们的实现应该基于ICU,但没有这些功能。但ICU确实使用历史时区inf格式化。创建一个答案,我可以选择它。谢谢!StackOverflow上通常不鼓励只链接的答案。可能最好只是关闭这个问题。
#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