【问题标题】:put_time() ignores conversion specifier 'z' for time zone offsetput_time() 忽略时区偏移的转换说明符“z”
【发布时间】: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(&current_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 和字段BiasDaylightBias 的解决方法,这是一个特定于平台的Windows-API。感谢您提供更安全的建议。

感谢您的帮助和见解!

环境:
带有 GCC 9.1.0 的 GNU/Linux (Archlinux)
带有 GCC 8.3.0 (MSYS2) 的 Windows

【问题讨论】:

  • 您是如何将源代码复制到 Windows 的?您是否重写了代码并错误地使用了大写的Z?大写的Z 将打印时区名称或其缩写。
  • 使用颠覆。这也是我的第一个假设。
  • 好的,那应该是一样的。 :) 您是否尝试更改为大写 Z 并查看它在 Windows 上打印的内容?可能是 Windows 实现中存在切换大小写含义的错误?
  • 也这样做了,同样的结果:)

标签: c++ windows time gnu


【解决方案1】:

如果您愿意使用free, open-source (MIT license) 3rd party library,它将提供可移植的结果。

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

int
main()
{
    using namespace date;
    using namespace std;
    using namespace std::chrono;
    zoned_seconds zt{current_zone(), floor<seconds>(system_clock::now())};
    cout << format("%c %z", zt) << '\n';
}

虽然在 Windows 上您需要安装 curl7-zip,但在 linux 上您需要与 -lcurl 链接。更详细的installation instructions are available here

这是 C++20 &lt;chrono&gt; 库草案的预览,尽管由于上周在科隆举行的投票,format 语句的语法将略有变化。 C++20 将合并fmt library(这是个好消息)。

这个库仍然使用put_time 作为格式的%c 部分,但格式化%z 部分本身(并根据需要在[+/-]hhmm 格式中给出偏移量)。

【讨论】:

  • 谢谢。我赞成你的回答,因为我希望它通过格式化自己来修复它,就像你提到的那样。当我读到一些关于它的东西时,它并不知道它会自行格式化。尽管我们现在不会跳到 C++20 或在这种情况下添加更多库。
猜你喜欢
  • 2017-11-22
  • 1970-01-01
  • 2012-06-05
  • 2015-05-11
  • 1970-01-01
  • 2016-01-02
  • 2016-12-07
  • 2016-01-15
  • 1970-01-01
相关资源
最近更新 更多