unix time と2038年問題
「不正な時刻が悪さをする」ということで聴いてみると、いわゆるunix timeとして正しく扱えないということのよう。ライブラリがエラーを返すらしい。とあるRTOSの開発環境の話であるけれども、手元にコンパイラでどうなるか調べてみました。
Visual C++ 2005
time_t が8バイトに拡張されていて、2038年問題は起きなくなってます。
が、-1を指定してctime()を呼び出すと不正割り込み発生。
ctime()では値として 0x0000000793406fff - Thu Jan 01 07:59:59 3001 までが正しく扱える範囲ですね。
sizeof(time_t) is 8 bytes sizeof(time_t) is 8 bytes 0x0000000000000000 - Thu Jan 01 00:00:00 1970 0x000000007ffffffe - Tue Jan 19 03:14:06 2038 0x000000007fffffff - Tue Jan 19 03:14:07 2038 0x0000000080000000 - Tue Jan 19 03:14:08 2038 0x0000000080000001 - Tue Jan 19 03:14:09 2038 0x00000000ffffffff - Sun Feb 07 06:28:15 2106
Borland C++ 5.82
負数の範囲は正しく扱えない模様。
sizeof(time_t) is 4 bytes 0x00000000 - Thu Jan 01 00:00:00 1970 0x7ffffffe - Tue Jan 19 03:14:06 2038 0x7fffffff - Tue Jan 19 03:14:07 2038 0x80000000 - (null) 0x80000001 - (null) 0xffffffff - (null)
g++ on Linux
負数は1970年1月1日から遡っていく仕様。
sizeof(time_t) is 4 bytes 0x00000000 - Thu Jan 1 00:00:00 1970 0x7ffffffe - Tue Jan 19 03:14:06 2038 0x7fffffff - Tue Jan 19 03:14:07 2038 0x80000000 - Fri Dec 13 20:45:52 1901 0x80000001 - Fri Dec 13 20:45:53 1901 0xffffffff - Wed Dec 31 23:59:59 1969
確認したプログラム
#ifdef __BORLANDC__ #include <stdio.h> #include <time.h> #define putenv(s) { _timezone = 0; } #else #include <cstdio> #include <ctime> #include <cstdlib> #ifdef _MSC_VER #define putenv(s) _putenv(s) #endif #endif void show(time_t t) { if (sizeof(time_t) == 8) { printf("0x%016llx - ", static_cast<long long>(t)); } else { printf("0x%08x - ", t); } char *p = ctime(&t); if (p) { printf(ctime(&t)); } else { puts("(null)"); } } int main() { putenv("TZ=GMT"); printf("sizeof(time_t) is %d bytes\n", sizeof(time_t)); show(0); show(0x7ffffffe); show(0x7fffffff); show(0x80000000); show(0x80000001); show(0xffffffff); }