为什么 struct tm 中的 tm_year 成员相对于 1900 而不是 macOS 上 C 中的 1970?

问题描述 投票:0回答:3

当我遇到这个问题时,我正在尝试专家 C 编程中的示例。我的程序基本上做了一件事:使用标准

gmtime
函数并查看自 1970 年以来已经过去了多少年。 这是我的程序:

#include <stdio.h>
#include <time.h>

int main(int argc, char** argv) {
    time_t now = time(0);
    struct tm *t = gmtime(&now);
    printf("%d\n", t->tm_year);
    return 0;
}

输出为117,即过去1900的年数。这是出乎意料的,因为我事先检查了

time()
man gmtime
,他们都说它们是相对于大纪元时间(1970-1-1 00:00:00):

time() returns the time as the number of seconds since the Epoch,
1970-01-01 00:00:00 +0000 (UTC).

http://man7.org/linux/man-pages/man2/time.2.html

The ctime(), gmtime() and localtime() functions all take an argument of data type 
time_t, which represents calendar time.  When interpreted as an absolute time 
value, it represents the number of seconds elapsed since the Epoch, 1970-01-01 
00:00:00 +0000 (UTC).

http://man7.org/linux/man-pages/man3/ctime.3.html

根据上面的描述,我的程序应该返回47而不是117。这是怎么回事?

macos sierra 10.12.5
Darwin 16.6.0 Darwin Kernel Version 16.6.0: Fri Apr 14 16:21:16 PDT 2017; root:xnu-3789.60.24~6/RELEASE_X86_64 x86_64
Apple LLVM version 8.1.0 (clang-802.0.42)
c macos time.h
3个回答
13
投票

所有
POSIX 兼容平台上,tm_year 字段相对于 1900,而不仅仅是在 macOS 上。

struct tm
旨在解析、显示和操作人类可读的日期。当它被创建时,日期通常被写入甚至存储,而没有年份数字的“19”部分,而千禧年问题距今大约还有 25 年。因此,通过将
tm_year
相对于 1900 年直接打印为两位数字,在当时看来是合理的。

Unix 时间戳是相对于“Unix 纪元”而言的,即 1970-01-01 00:00:00 UTC。至于原因,请参阅此问答


3
投票

tm_year
struct tm
成员与每个 C 库规范的 1900 相关。 所有兼容的标准库都使用它。

tm
结构应至少包含以下成员,顺序不限。成员的语义及其正常范围在注释§7.27.2.1 4

中表达
...
int tm_year; // years since 1900

time()
返回一个
time_t
值“可能代表一个 基于特定纪元的日历时间”。这通常是 1970 年 1 月 1 日 0:00:00 世界时间。*nix 系统遵循这一点。C 不需要这个纪元 1 月 1 日,并且不直接与
tm_year
struct tm
成员的纪元。


0
投票

感谢大家分享这些信息

© www.soinside.com 2019 - 2024. All rights reserved.