календарное время, хранящееся в виде 32-битного целого числа со знаком — когда оно переполнится

Я выполняю упражнения из Advanced Programming in Unix и столкнулся со следующим вопросом:

Если календарное время хранится в виде 32-битного целого числа со знаком, в каком году оно переполнится?

положительное целое число со знаком = 2147483647

В следующем расчете я не учитываю високосные годы:

((((2147483647 / 60sec) /60min)/24)/365) = 68.1yrs

Это наивный подход. Как я могу подойти к этому вопросу профессионально?

Следующее решение, представленное ранее членом стека, очень помогло распечатать год.

int epoch_time = INT_MAX;
struct tm * timeinfo;
time_t epoch_time_as_time_t = epoch_time;
timeinfo = localtime(&epoch_time_as_time_t);
printf("2] overflow date: %s", asctime(timeinfo));

person dcrearer    schedule 26.01.2017    source источник
comment
Для меня ваш подход правильный.   -  person Jabberwocky    schedule 26.01.2017
comment
@MichaelWalz, это не совсем правильно, так как он использует 365 дней в году, на самом деле цифра составляет 365 242 ...   -  person M.M    schedule 26.01.2017
comment
Вы предполагаете какую-то конкретную эпоху? Существует стандартная эпоха unix, но вы можете использовать другую эпоху, если хотите.   -  person M.M    schedule 26.01.2017
comment
Это известно как проблема 2038 года. У меня есть целый доклад об этом под названием ПОКАЯТЕСЬ, ИБО КОНЕЦ ЭПОХИ UNIX БЛИЗКО! (извиняюсь за плохой звук)   -  person Schwern    schedule 26.01.2017
comment
@M.M Я написал подход правильный, и ОП заявил, что он не учитывает високосные годы.   -  person Jabberwocky    schedule 26.01.2017


Ответы (3)


когда он переполнится

Предполагая, что на рассматриваемой платформе int имеет ширину 32 бита (а time_t является интегральным типом, скажет, например, что это не struct), просто выполните

printf("%s\n", asctime(localtime(&(time_t){difftime(INT_MAX, 0)})));

и ты знаешь.

Он печатает:

Tue Jan 19 04:14:07 2038

Обменяв аргументы на difftime(), можно получить «самую раннюю» дату, BTW:

printf("%s\n", asctime(localtime(&(time_t){difftime(0, INT_MAX)})));

отпечатки

Fri Dec 13 21:45:53 1901
person alk    schedule 26.01.2017

Одним из способов было бы использование команды UNIX date. В частности, date -d '@<seconds>' выводит дату и время, соответствующие <seconds> секундам с эпохи UNIX. Кроме того, вы можете указать спецификатор формата +%Y, если вас интересует только год.

Итак, для этого примера вы должны выполнить

date -d '@2147483647' +%Y

и увидит вывод 2038.

person Brett Boston    schedule 26.01.2017
comment
Эпоха - 1 января 1970 года, поэтому, если я добавлю результат моего расчета, дата переполнения будет 2038 года. - person dcrearer; 26.01.2017

Подход может показаться наивным, но он почти точен. Вам нужно учитывать високосные годы и, возможно, високосные секунды.

На странице Википедии, посвященной времени UNIX, где-то упоминается 2038 год. Там вы найдете остальные детали.

person Roland Illig    schedule 26.01.2017