Я думаю, что следующая программа должна выводить секунды до 1970 года в первый день каждого года с 1 до 1970 года, которому предшествует размер time_t
в системе, на которой он скомпилирован ( CHAR_BIT
– это макрос, поэтому я думаю, что вы не можете просто скопировать скомпилированный исполняемый файл и предполагающий его правильность, хотя на практике все использует 8-битный char
эти дни).
#include #include #include #include #include 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) это работает только в течение лет> = 1902, несмотря на то, что time_t
составляет 64 бит. Я мог бы понять, были ли программисты в Apple ленивыми и не поддерживали каких-либо лет до 1970 года, но правильное поведение, начатое в 1902 году, а затем прекращение выглядит скорее как ошибка с моей стороны.
Консультирование по стандарту C:
Диапазон и точность времени, представляемого в
clock_t
иtime_t
определяются реализацией. [..][N1570 §7.27.1 / 4] (акцент мой)
И далее, относительно mktime
:
Функция
mktime
возвращает указанное время календаря в виде значения типаtime_t
. Если календарное время не может быть представлено, функция возвращает значение(time_t)(-1)
.[N1570 §7.27.2.3 / 3]
Таким образом, если возвращаемое значение mktime
равно (time_t)(-1)
за годы, когда оно не работает … вы сами по себе.
На самом деле, IMO, стандарт немного тихий обо всем этом:
[..]
int tm_year; // years since 1900
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, которые делают то, что вы хотите, и пытаетесь использовать их код (если это возможно в отношении любых лицензий, которые вам нужно соблюдать). Вот тот, который использует моя система.
В ОС UNIX часто используются версии временных функций с поддержкой 64 бит. OS X может иметь что-то подобное, хотя я не мог найти его с помощью моего быстрого поиска. Для получения дополнительной информации см. 64-битное временное преобразование unix .
EDIT: Я нашел Mac, чтобы проверить это, и, похоже, у него нет функции mktime64. Я нашел эту библиотеку, которая могла бы работать как работа, хотя я не проверял ее лично.