如何获得date(1)/ mktime(3)所代表/接受的日期范围?

时间:2017-09-21 01:02:16

标签: macos date posix libc bsd

在我的现代64位Mac上,日期1901-12-14是最早被以下命令接受的:

date -ju -f "%F" "1901-12-14" "+%s"

我检查了macOS date命令here (Apple Open Source)的来源,这是一个失败的mktime调用,导致早期日期出现date: nonexistent time错误。

我查看了mktime here (Apple Open Source)的来源,我认为这是一个整数表示问题,但我不确定。

如何查找或计算date命令(实际上为mktime)的可接受日期范围?

如果我想获得一个无法由mktime内部代表的日期的Unix时间,那么其他哪些库或函数可以处理更早的日期?

1 个答案:

答案 0 :(得分:1)

mktime(3)的当前macOS(OS X)实现的最低支持Unix时间为INT32_MIN-2147483648)。这是因为localtime.c:2102假设如果值小于INT32_MAX,则结果将适合32位整数:

/* optimization: see if the value is 31-bit (signed) */
t = (((time_t) 1) << (TYPE_BIT(int) - 1)) - 1;
bits = ((*funcp)(&t, offset, &mytm) == NULL || tmcomp(&mytm, &yourtm) < 0) ? TYPE_BIT(time_t) - 1 : TYPE_BIT(int) - 1;

1901-12-14 1901-12-13 之间,Unix时间低于INT32_MIN,需要超过32位,并且仍然少于比INT32_MAX导致函数用完bits

考虑到localtime.c:2073明确禁止1900年之前的价值,这不是什么大问题:

/* Don't go below 1900 for POLA */
if (yourtm.tm_year < 0)
        return WRONG;

(POLA:最小惊讶原则)

此外,time_t不是required to be signed