【发布时间】:2020-02-15 01:02:48
【问题描述】:
考虑以下 C++ 代码
#include <ctime>
#include <iostream>
int main()
{
std::time_t now = std::time(nullptr);
struct tm local = *std::localtime(&now);
struct tm gm = *std::gmtime(&now);
char str[20];
std::strftime(str, 20, "%Z", &local);
std::cout << str << std::endl; // HKT
std::strftime(str, 20, "%Z", &gm);
std::cout << str << std::endl; // UTC
return 0;
}
所以存储在now 中的是一个明确的整数值,而local 和gm 是struct tm 存储人类可读的日期/时间信息。然后我打印出仅基于struct tm 对象的格式化信息(时区)。
根据cplusplusreference,struct tm的数据成员是
tm_sec
tm_min
tm_hour
tm_mday
tm_mon
tm_year
tm_wday
tm_yday
tm_isdst
如果这就是struct tm 包含的全部内容,程序如何知道其中的时区信息?也就是说,它怎么知道local的时区是HKT,gm的时区是UTC?
如果struct tm 包含的内容不止这些,请说明它是如何存储时区信息的。
顺便说一句,虽然演示代码是用 C++ 编写的,但我想这个问题本质上也是一个合法的 C 问题。
【问题讨论】:
-
tm不包含时区信息。strftime通过幕后巫术获取时区。如果你想获得一般的时区,那就有点乱了。 (currently) 没有获取时区的标准方法。 Fortunately Howard Hinnant is on that job.... -
谢谢@user4581301 这部分回答了我的问题。但我还有后续问题:鉴于
tm中存储的所有信息,strftime如何知道以不同方式响应两个struct tm对象?除非tm包含诸如thistmis created bylocaltime之类的信息,thattmis created bygmtime。 -
tm结构不存储时区信息,是什么让您认为它可以存储?区别在于对gmtime()和localtime()的调用。 -
Man page 涵盖了如何在 POSIX 系统上获取时区信息。仍在寻找
strftime如何区分吸盘。应该添加 POSIX 未定义发生的事情。 -
在 Windows 下使用来自 MSYS2 的 gcc 9.2.0 彻底失败。看到这让我想起了我看到的非标准
tms 有额外的信息。 Here's one。注意const char *tm_zone成员。你是为什么平台编译的?看看tm的实现,看看他们是否扩展了结构。