【问题标题】:Cross-platform way to convert UTC tm* to localized tm*?将 UTC tm* 转换为本地化 tm* 的跨平台方法?
【发布时间】:2012-09-13 20:46:28
【问题描述】:

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

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

到目前为止,我一直采用的方法是仅使用 POSIX 日期和时间函数,并在必要时编写 Windows 垫片(目前已为 strptime() 完成,如果需要,可能在将来为 timegm() 完成)。我宁愿继续这样做,但简单的事实是 Windows 中的 tm* 结构缺少 Linux 和 OSX 所做的一些字段,所以我可能别无选择,只能编写由 @ 保护的不可移植代码987654330@。我也真的不希望为此付出任何努力。

【问题讨论】:

  • 即使您不想使用 boost,如果这样可以解决问题,我仍然建议您使用 boost...

标签: c++ windows linux macos time


【解决方案1】:

给定一个struct tm *utc_tm,您可以使用(非便携式)timegm 将其转换为time_t utc,然后使用localtime 将其转换为struct tm *local_tm

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

【讨论】:

  • 你的回答起初让我很困惑,因为这是我放弃的方法;我的错误印象是 time_t 在 Windows 上按时区移动。然而,仔细查看 MSDN,证实了您的方法的正确性。谢谢!
猜你喜欢
  • 1970-01-01
  • 2012-06-22
  • 2015-09-09
  • 2015-05-06
  • 2023-03-17
  • 2022-01-24
  • 1970-01-01
  • 2014-02-02
相关资源
最近更新 更多