c++ - 为什么使用 %z 格式的 std::put_time(std::gmtime 会为 UTC 返回 +0100?
问题描述
我在下面有这个小例子,它给了我不明白的结果。
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
int main() {
auto currentTime = std::time(nullptr);
auto currentTime2 = std::time(nullptr);
std::stringstream ss;
std::stringstream ss2;
ss << std::put_time(std::localtime(¤tTime), "%Y-%m-%dT%H:%M:%S %z %Z");
ss2 << std::put_time(std::gmtime(¤tTime2), "%Y-%m-%dT%H:%M:%S %z %Z");
std::cout << " time now local = " << ss.str() << std::endl;
std::cout << " time now gm = " << ss2.str() << std::endl;
}
在 Windows (VS2017) 上,这给了我:
time now local = 2019-10-08T16:25:17 +0200 W. Europe Summer Time
time now gm = 2019-10-08T14:25:17 +0100 W. Europe Standard Time
在 Mac(XCode 10)上,这给了我:
time now local = 2019-10-08T16:25:17 +0200 CEST
time now gm = 2019-10-08T14:25:17 +0100 UTC
有人可以向我解释为什么 %z 为 UTC 输出提供 +0100 而不是 +0000?我缺少逻辑的哪一部分?
例如,在http://ideone.com/IspjpG上运行它总是给出 +0000。
解决方案
std::tm
由返回的类std::gmtime
并且std::localtime
不包含时区信息,除了夏令时是否生效。对于gmtime
,它永远不会生效,对于localtime
,它取决于当前的语言环境和时间。
%Z
格式说明符std::put_time
使用当前语言环境获取时区信息。当前活动的语言环境不受std::tm
作为参数给出的对象的影响。
因此,在第一种情况下,您打印本地时间以及有关本地时区的信息(启用 DST)。在第二种情况下,您打印 UTC 时间以及有关本地时区的信息(禁用 DST)。
我们可以得出结论,使用%z
and%Z
打印来自其他时区而不是当前本地时区的时间是不正确的。坦率地说,我认为它是std::put_time
接口(以及包装的接口)中的一个缺陷std::strftime
,std::put_time
即无法将时区信息传递给函数,但可能会意外打印可能与std::tm
正在打印的实例无关的时区。
要获得正确的输出,您应该使用:
ss2 << std::put_time(std::gmtime(¤tTime2),
"%Y-%m-%dT%H:%M:%S +0000 UTC");
推荐阅读
- reactjs - 会话 cookie 不与 XHR 请求一起发送
- php - 如何在 Markmail 支持中写问题(即开放会议支持)
- angular - 如何使用 cdkDropListEnterPredicate 检查多个条件?
- android - React Native:自定义标题未设置为标题导航
- c++ - Visual Studio 2019 中的自动递增 FileVersion (build nr)
- mysql - 使用 sequelize 和 MySQL 方言生成模型
- node.js - 如何使这个 axios 删除请求起作用?
- sql - 使用公共列 POSTGRESQL 在两个表之间映射不同的值
- javascript - 用if条件分割字符串 - JS
- javascript - vue.set() 一个 vuex 突变中的数组