【发布时间】:2019-12-04 16:59:38
【问题描述】:
以下代码应打印带有时区偏移量的时间,传递小写格式说明符z:
#include <iostream>
#include <iomanip>
#include <ctime>
using namespace std;
int main() {
time_t current_time = time(nullptr);
tm* timeinfo = localtime(¤t_time);
cout << put_time(timeinfo, "%c %z") << "\n";
return 0;
}
g++ -o time time.cpp -Wall -pedantic
cppreference.com 上描述了函数 put_time() (C++)。格式说明符来自strftime() (C)。您也可以在C Standard 中了解它们,当前页面 396 在第 7.27.3.5 章中:
%z被 ISO 8601 格式“-0430”(意思是 4 比 UTC 时间晚 30 分钟,格林威治以西),或者如果没有时间则不加字符 区域是可确定的。 [tm_isdst]
这在 Linux 上运行良好:
2019 年 7 月 26 日星期五 12:30:02 +0200
但在 Windows 上它会返回:
07/26/19 12:03:53 Mitteleuropäisches Sommerzeit
错了,我的代码没有询问时区的名称,而是询问与 UTC 的偏移量。我在两个平台上都使用 GCC 作为编译器。
问题
我在这里做错了吗?还是 GCC 或 Microsoft Windows 违反了标准?我读到了一些“谣言”,说它可能会受到 Windows 上的某些设置的影响。
手动计算偏移量是相当危险的。最好的助手是tm.gmt_offset,这是平台特定的字段。因此gmt_offset 未列出,仅在基于 GNU 的系统上可用。我目前正在使用基于GetTimeZoneInformation 和字段Bias 和DaylightBias 的解决方法,这是一个特定于平台的Windows-API。感谢您提供更安全的建议。
感谢您的帮助和见解!
环境:
带有 GCC 9.1.0 的 GNU/Linux (Archlinux)
带有 GCC 8.3.0 (MSYS2) 的 Windows
【问题讨论】:
-
您是如何将源代码复制到 Windows 的?您是否重写了代码并错误地使用了大写的
Z?大写的Z将打印时区名称或其缩写。 -
使用颠覆。这也是我的第一个假设。
-
好的,那应该是一样的。 :) 您是否尝试更改为大写
Z并查看它在 Windows 上打印的内容?可能是 Windows 实现中存在切换大小写含义的错误? -
也这样做了,同样的结果:)