我认为以下程序应将每年的第一天从1AD到1970的秒数输出到1970,time_t
并在其上进行编译的系统上的大小(CHAR_BIT
是宏,因此我认为您不能只复制已编译的可执行文件并假设它是正确的,尽管实际上现在所有东西都使用8位char
)。
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
void do_time(int year)
{
time_t utc;
struct tm tp;
memset(&tp, 0, sizeof(tp));
tp.tm_sec = 0;
tp.tm_min = 0;
tp.tm_hour = 0;
tp.tm_mday = 1;
tp.tm_mon = 0;
tp.tm_year = year - 1900;
tp.tm_wday = 1;
tp.tm_yday = 0;
tp.tm_isdst = -1;
printf("%d %ld\n",year, mktime(&tp));
}
int main(){
printf("time_t is %lu bits\n",sizeof(time_t)*CHAR_BIT);
for (int i = 1; i<1971; i++)
do_time(i);
exit(0);
}
但是,在OS X(10.11.3 15D21)上,尽管time_t
具有64位签名,但它只能在> = 1902年使用。我可能理解苹果的程序员是否懒惰并且在1970年之前没有任何支持,但是正确的行为可以追溯到1902年,然后停下来看起来更像是我的错误。
咨询C标准:
的范围和次精度所能表述中
clock_t
和time_t
是实现定义。[..][N1570§7.27.1/ 4](强调我的)
再往下看,关于mktime
:
该
mktime
函数返回指定的日历时间,该时间编码为type的值time_t
。如果无法表示日历时间,则该函数返回值(time_t)(-1)
。[N1570§7.27.2.3/ 3]
因此,只要的返回值mktime
是(time_t)(-1)
在不起作用的年份中,您就可以自己承担责任。
实际上,IMO对所有这些标准都保持沉默:
[..]
int tm_year; // years since 1900
[..][N1570§7.27.1/ 4]
这可能意味着自1900年以来的(正)年,但是为什么要使用带符号整数。
附带说明:在我的系统(Linux 3.14.40 x86_64 glibc-2.21)上,我得到...
time_t is 64 bits
1 -62135600008
...
1969 -31539600
1970 -3600
考虑到周围的工作:您当然可以查看正在执行所需操作的libc实现,并尝试使用其代码(如果您需要遵守的任何许可证都是可行的)。这是我的系统使用的那个。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句