BTW, ctime (& ctime(3)) документирована как дает строку года, представленной четыре цифр (в общей сложности 26 байт). Таким образом, максимальное время в году 9999 (конечно, меньше максимального time_t
на машине с 64 бит time_t
).
Кроме того, как я уже говорил, прагматично, если time_t
имеет более 40 бит (например, 64 бит), вам не важно максимально отображаемое время. Вы и все, кто читает этот форум (и все наши великие дети), будут мертвы, компьютеры, на которых запущена ваша программа, будут уничтожены, и в это время C больше не будет существовать. Y2038 problem практически не имеют эквивалентов в 64 бита. Так что только особый случай, когда time_t
- 32 бит.
Очень маловероятно, чтобы любая программа C имела бы значение после 3000 года; программное обеспечение, аппаратные средства, стандарты и человеческие технические знания не длятся так долго ...
POSIX ctime documentation говорит явно:
Attempts to use ctime()
or ctime_r()
for times before the Epoch or for times beyond the year 9999 produce undefined results. Refer to asctime .
BTW, musl-libc, кажется, соответствует стандартному: its time/__asctime.c
(косвенно вызывается ctime
) имеет хороший комментарий:
if (snprintf(buf, 26, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
__nl_langinfo(ABDAY_1+tm->tm_wday),
__nl_langinfo(ABMON_1+tm->tm_mon),
tm->tm_mday, tm->tm_hour,
tm->tm_min, tm->tm_sec,
1900 + tm->tm_year) >= 26)
{
/* ISO C requires us to use the above format string,
* even if it will not fit in the buffer. Thus asctime_r
* is _supposed_ to crash if the fields in tm are too large.
* We follow this behavior and crash "gracefully" to warn
* application developers that they may not be so lucky
* on other implementations (e.g. stack smashing..).
*/
a_crash();
}
и GNU glibc
имеет I п его time/asctime.c файл:
/* We limit the size of the year which can be printed. Using the %d
format specifier used the addition of 1900 would overflow the
number and a negative vaue is printed. For some architectures we
could in theory use %ld or an evern larger integer format but
this would mean the output needs more space. This would not be a
problem if the 'asctime_r' interface would be defined sanely and
a buffer size would be passed. */
if (__glibc_unlikely (tp->tm_year > INT_MAX - 1900))
{
eoverflow:
__set_errno (EOVERFLOW);
return NULL;
}
int n = __snprintf (buf, buflen, format,
(tp->tm_wday < 0 || tp->tm_wday >= 7 ?
"???" : ab_day_name (tp->tm_wday)),
(tp->tm_mon < 0 || tp->tm_mon >= 12 ?
"???" : ab_month_name (tp->tm_mon)),
tp->tm_mday, tp->tm_hour, tp->tm_min,
tp->tm_sec, 1900 + tp->tm_year);
if (n < 0)
return NULL;
if (n >= buflen)
goto eoverflow;
Поэтому я считаю, что и GNU Glibc и MUSL-Libc лучше, чем реализация MacOSX (в цитируемой в zneak's answer) на этом аспекте. Стандартам требуется ctime
, чтобы получить 26 байтов. Кроме того, POSIX 2008 маркирует ctime
как устаревшее, новый код должен использовать strftime (см. Также strftime(3)).
«При возникновении ошибки эти функции возвращают« NULL »и устанавливают« errno »в соответствующее значение». Что говорит 'perror'? – zneak
Действительно, есть ошибка. Ошибка: неверный аргумент. – pbn
Прагматически, если 'time_t' имеет более 40 бит (например, 64 бит), вам не важно максимально отображаемое время. Вы и все, кто читает этот форум (и все наши великие дети), будут мертвы, компьютеры, на которых запущена ваша программа, будут уничтожены, и в это время C больше не будет существовать. Проблема [Y2038] (http://en.wikipedia.org/wiki/Year_2038_problem) практически не имеет эквивалента в 64 бита. Так что только особый случай 'time_t' - 32 бита. –