I was trying out the examples in expert C programming while I encountered this problem. My program basically does one thing: use the standard gmtime
function and see how many years has past since 1970.
Here is my program:
#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. 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() 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
According to the above description, my program should have returned 47 instead of 117. What is going on here?
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.
The struct tm
is designed for parsing, displaying, and manipulating human-readable dates. 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. So the convenience of making tm_year
directly printable as two digits, by making it relative to 1900, apparently seemed reasonable at the time.
Unix timestamps are relative to the “Unix epoch”, which is 1970-01-01 00:00:00 UTC. For the reasons why, see this Q&A.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With