简体   繁体   English

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

[英]Why is the tm_year member in struct tm relative to 1900 rather than 1970 in C on macosx?

I was trying out the examples in expert C programming while I encountered this problem. 遇到此问题时,我正在尝试使用专家C编程编写示例。 My program basically does one thing: use the standard gmtime function and see how many years has past since 1970. Here is my program: 我的程序基本上做一件事:使用标准的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;
}

The output is 117 , the number of years past 1900 . 输出为117 ,即1900年之后的年数 This is unexpected because I checked time() and man gmtime beforehand and they both said they are relative to the Epoch time (1970-1-1 00:00:00): 这是意外的,因为我事先检查了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 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 http://man7.org/linux/man-pages/man3/ctime.3.html

According to the above description, my program should have returned 47 instead of 117. What is going on here? 根据上面的描述,我的程序应该返回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)

The tm_year field is relative to 1900 on all POSIX-compliant platforms, not just on macOS. 所有 POSIX兼容平台上,不仅在macOS上, tm_year字段都相对于1900。

The struct tm is designed for parsing, displaying, and manipulating human-readable dates. struct tm设计用于解析,显示和处理人类可读的日期。 When it was created, dates were commonly written and even stored without the “19” part of the year number and the Y2K problem was around 25 years away. 创建日期时,通常会写日期,甚至存储日期时也不会包含年份数字中的“ 19”部分,并且距Y2K问题大约还有25年的距离。 So the convenience of making tm_year directly printable as two digits, by making it relative to 1900, apparently seemed reasonable at the time. 因此,使tm_year相对于1900成为直接可两位数打印的便利,在当时似乎很合理。

Unix timestamps are relative to the “Unix epoch”, which is 1970-01-01 00:00:00 UTC. Unix时间戳相对于“ Unix纪元”,即1970-01-01 00:00:00 UTC。 For the reasons why, see this Q&A . 出于这个原因, 请参阅此问答

The tm_year member of struct tm is relative to 1900 per the C library specification. 根据C库规范, struct tmtm_year成员相对于1900。 All compliant standard libraries use that. 所有符合标准的库都使用该库。

The tm structure shall contain at least the following members, in any order. tm结构至少应按任何顺序包含以下成员。 The semantics of the members and their normal ranges are expressed in the comments §7.27.2.1 4 成员的语义及其正常范围在第7.27.2.1条注释中表示4

...
int tm_year; // years since 1900

time() returns a time_t value "which may represent a calendar time based on a particular epoch". time()返回time_t值“可以表示基于特定纪元的日历时间”。 This is commonly 1970, Jan 1, 0:00:00 universal time. 这通常是世界标准时间1970年1月1日0:00:00。 *nix systems adhere to that. * nix系统坚持这一点。 This epoch of Jan 1, is not required by C and is not connected direclty to the epoch to the tm_year member of struct tm . C不需要1月1日这一时期,并且与struct tmtm_year成员的时期没有直接的tm_year

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM