C++ 到特定时区的历元时间转换

C++ 到特定时区的历元时间转换,c++,winapi,C++,Winapi,我需要把UNIX大纪元时间转换成东部夏时制 std::time_t curtime = timestamp[i]; char buff[30]; strftime(buff, 30, strTimeStampFormat.c_str(), localtime(&curtime)); 为我提供时区和纽约之间的时间偏移转换。如何做到这一点?我正在考虑重新计算,但是我应该使用什么时间相关的WinAPI呢 我试过了,但是如何处理夏令时呢 std::time_t curtime

我需要把UNIX大纪元时间转换成东部夏时制

std::time_t curtime = timestamp[i];
char buff[30];
strftime(buff, 30, strTimeStampFormat.c_str(), localtime(&curtime));
为我提供时区和纽约之间的时间偏移转换。如何做到这一点?我正在考虑重新计算,但是我应该使用什么时间相关的WinAPI呢

我试过了,但是如何处理夏令时呢

        std::time_t curtime = timestampint[i];
        char buff[30];
        struct tm * ptm;
        ptm = gmtime(&curtime);
        ptm->tm_hour = (ptm->tm_hour - 4) % 24;
        strftime(buff, 30, strTimeStampFormat.c_str(), ptm);
        timestampstring.push_back(std::string(buff));

如果我正确理解了您的问题,您希望以美国/纽约当地时间格式设置秒精度戳记,而不考虑计算机的本地时区设置。我假设您希望以线程安全的方式执行此操作,而无需重置计算机的本地时区

这可以在C++20中轻松安全地完成。我知道你现在没有C++20,因为它还没有上市。但也存在一个问题

现在有两种不同的方法可以使用它,每种方法都有各自的优缺点。首先,这里是它在C++20中的样子:

#include <chrono>
#include <fmt>
#include <iostream>
#include <sstream>

std::string
New_York(std::time_t currtime, std::string strTimeStampFormat = "{:%F %T %Z}")
{
    using namespace std;
    using namespace std::chrono;

    sys_seconds tp{seconds{currtime}};
    zoned_seconds zt{"America/New_York", tp};
    ostringstream os;
    os << format(strTimeStampFormat, zt);
    return os.str();
}

int
main()
{
    std::cout << New_York(std::time_t{1599580658}) << '\n';
}
第一步是将
time\u t
转换为
std::chrono::time\u点
sys_seconds
是此类型的类型别名

接下来,与std::chrono::time_zone
“America/New_York”
形成“配对”,存储在名为
分区秒
的类型中。这种类型能够在UTC和纽约当地时间之间转换,同时考虑到夏令时规则,甚至可以追溯到一个世纪前这些规则的变化

最后,您可以使用熟悉的格式化标志格式化此
zoned_time
,这些标志与
strftime
一起使用

此程序不关心计算机当前本地时区的设置,也不改变全局时区。一个程序可以安全地格式化为多个时区,即使在单独的并发线程中也是如此

今天要做到这一点,在C++11、C++14或C++17中,可以使用,但它会。该链接上有Windows特定的说明。源代码略有变化:

#include "date/tz.h"
#include <chrono>
#include <iostream>
#include <sstream>

std::string
New_York(std::time_t currtime, std::string strTimeStampFormat = "%F %T %Z")
{
    using namespace date;
    using namespace std;
    using namespace std::chrono;

    sys_seconds tp{seconds{currtime}};
    zoned_seconds zt{"America/New_York", tp};
    ostringstream os;
    os << format(strTimeStampFormat, zt);
    return os.str();
}
  • 标题更改为
    “date/ptz.h”
  • ptz.h
    中实现了自定义
    时区
    ,而不是使用标准(或预标准)
    时区
    ,并将其安装到秒精度
    分区时间
字符串
“EST5EDT,M3.2.0,M11.1.0”
是2007年至今纽约夏令时规则的POSIX模型。该程序可以很容易地移植到C++20,但仍然需要
date/ptz.h
中的header-only库来建模
Posix::time_zone

如果您使用的是C++17或更高版本,
zt
的声明/定义可以简化为:

    zoned_time zt{tz, tp};
因为模板参数可以由构造函数参数推导

使用和输出与以前相同

2020-09-08 11:57:38 EDT

我的案子结果很简单。一个单独的API提供了元信息,包括密钥对“gmtoffset”:“-14400”。因此,进行额外的API调用、解析json并提取GMT偏移量修复了这个问题。但是,上面的代码可以用作备用代码。

gmtime
代替
localtime
,怎么样?@goodvibration在问题中添加了注释。夏令时,如何处理呢?偏移量将为负4或负5@dgrandm在
struct tm
中,成员
tm_isdst
可以判断是否为夏令时。您也可以使用WinAPI
    zoned_time zt{tz, tp};
2020-09-08 11:57:38 EDT