c++ - 将 UTC tm* 转换为本地化 tm* 的跨平台方式?

标签 c++ windows linux macos time

这个问题已经困扰我好一分钟了。我正在开发一个用 C++ 编写的程序,我需要能够在两个不同的服务器之间发送以 ISO8601 编码的时间。这里的主要坚持者似乎是 Windows。

到目前为止,我已经从 NetBSD 移植了 strptime(),以便轻松地离线读取日期/时间字符串并将其转换为 tm*。但是,在正确地将其转换为本地化的 tm* 时,我完全被难住了,因此我可以使用 strftime() 在本地时区向用户显示这个时间.一种天真的方法是简单地采用 localtime(time(0))gmtime(time(0)) 之间的差异,但这对于涉及夏令时的任意日期。

到目前为止,我一直采用的方法是仅使用 POSIX 日期和时间函数,并在必要时编写 Windows 垫片(到目前为止为 strptime()timegm( ) 如有必要,可能在未来)。我宁愿继续这样做,但一个简单的事实是 Windows 中的 tm* 结构缺少 Linux 和 OSX 中的一些字段,所以我可能别无选择,只能编写不可移植的#if WIN32 保护的代码。我也真的不想为此增加动力。

最佳答案

给定一个struct tm *utc_tm,你可以使用(不可移植的)timegm将它变成一个time_t utc,然后把它变成一个struct tm *local_tm 使用 localtime:

time_t utc = timegm(utc_tm);
struct tm local_tm;
localtime_r(&utc, &local_tm);

据我所知,timegm 的最简单实现涉及使用月表和闰年计算自行进行转换。或者,如果您的 strptime 正确填写了 tm_yday,您可以使用 https://stackoverflow.com/a/9076848/567292 中的公式:

tm_sec + tm_min*60 + tm_hour*3600 + tm_yday*86400 +
    (tm_year-70)*31536000 + ((tm_year-69)/4)*86400 -
    ((tm_year-1)/100)*86400 + ((tm_year+299)/400)*86400

关于c++ - 将 UTC tm* 转换为本地化 tm* 的跨平台方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12530349/

相关文章:

windows - 如何获得在 Powershell 中使用 RSS 的特定 NIC 的 NUMA 差异

linux - 强制应用程序使用 Fedora 机器上的特定源端口

linux - 使用 "sudo service sshd restart"重新启动后无法使用 Linux 终端连接到 AWS 服务器。出现 “Connection timed out” 错误

c++ - 我什么时候不需要 typedef?

c++ - C++命名空间中的名称解析规则是什么?

c++ - 抽奖分类程序上的 EXC_BAD_ACCESS

linux - 共享库使用外部符号的计数

c++ - 多个按钮的插槽

Windows程序文件路径名?

windows - 如何在 Windows 上重置 Jenkins 的用户/密码?