Еще четыре функции применяются для преобразований времени из чисел, которые обрабатывает компьютер, в текстовые представления, удобные для человека. Последняя функция не входит в число стандартных вопреки своей очевидной всеобщей полезности.
char *asctime(struct tm *tp);
char *ctime(time_t *t);
asctime() и ctime() служат для преобразования временных значений в стандартную строку даты Unix, которая выглядит примерно так:
Tue Jun 17 23:17:29 1997
В обоих случаях длина сроки равна 26 символам и включает в себя завершающие символы новой строки и ' '.
Не во всех локалях длина строки обязательно равна 26 символам, как в стандартной локали С.
ctime() выражает указанную дату в местном времени; asctime() — в том часовом поясе, который указан в struct tm. Если последний объект был создан с помощью gmtime(), то в показателях UTC, если при помощи localtime(), то по местному времени.
size_t strftime (char *s, size_t max, char *fmt, struct tm *tp);
strftime() работает также как sprintf() для времени. Она форматирует struct tm в соответствии с форматом fmt и размещает результат в не более чем max байтах (включая завершающий символ ' ') строки s.
Подобно sprintf(), функция strftime() использует символ % для ввода управляющих последовательностей, в которые подставляются данные. Все подстановочные строки выражаются в показателях текущей локали. Однако сами управляющие последовательности являются совершенно разными. В некоторых случаях строчные буквы применяются для аббревиатур, а заглавные буквы — для полных имен. В отличие от sprintf(), здесь отсутствует опция употребления чисел в середине управляющей последовательности для ограничения длины подстановочной строки; выражение %.6А недопустимо. По аналогии с функцией sprintf(), strftime() возвращает количество символов, выведенных в буфер s. Равенство данной величины значению max означает, что объем буфера недостаточен для текущей локали; необходимо выделить больший буфер и попытаться снова.
strftime() использует те же самые подстановки, что и программа работы с датами. Ниже приводятся определения для подстановок в стандартной локали, они служат для того, чтобы помочь вам идентифицировать тип информации. В остальных локалях они могут отличаться.
%а Трехбуквенная аббревиатура для названия дня недели. %А Полное название дня недели. %b Трехбуквенная аббревиатура для названия месяца. %В Полное название месяца. %с Предпочтительное локальное выражение даты и времени (такое как возвращают функции ctime() и asctime()). %d День месяца в числовом виде (отсчет ведется от нуля). %Н Час дня по 24-часовому времени (отсчет ведется от нуля). %I Час дня по 12-часовому времени (отсчет ведется от нуля). %j День года (отсчет ведется от единицы). %m Месяц года (отсчет ведется от единицы). %М Минута в часе (отсчет ведется от нуля). %p Соответствующая строка для локального эквивалента выражений AM или PM. %S Секунда в минуте (отсчет ведется от нуля). %U Неделя года в числовом виде (первая неделя начинается с первого воскресенья года). %W Неделя года в числовом виде (первая неделя начинается с первого понедельника года). %w День недели в числовом виде (отсчет ведется с нуля). %x Предпочтительное локальное выражение только для даты, без времени. %X Предпочтительное локальное выражение только для времени, без даты. %y Двухзначное представление года (без столетия). Не рекомендуется использовать такой формат — это потенциальный источник "проблемы 2000-го года". %Y Полное четырехзначное числовое представление года. %Z Название стандартной аббревиатуры часовой зоны. %% Буквенный символ %.
char *strptime(char *s, char *fmt, struct tm *tp);
Как и scanf(), функция strptime() преобразует строку в разобранный формат. Она пытается быть либеральной при интерпретации введенной строки s в соответствии с форматирующей строкой fmt. Она принимает те же самые управляющие последовательности, что и strftime(), при этом для каждого типа ввода она допускает как аббревиатуры, так и полные имена. Она не различает символы верхнего и нижнего и регистра, а также не распознает %U и %W.
Функция strptime() предусматривает несколько дополнительных управляющих последовательностей; также она интерпретирует несколько последовательностей иначе (не так, как strftime()). В последующем списке перечислены только те управляющие последовательности, которые отличаются значительно (другими словами, выходят за рамки тех изменений, на которые мы уже указывали). Числа могут предваряться нулями, но это не обязательно.
%h Эквивалент %b и %B. %с Считывает дату и время так, как печатает функция strftime() с форматирующей строкой %x %X. %С Считывает дату и время так, как печатает функция strftime() с форматирующей строкой %с. %e Эквивалент %d. %D Считывает дату так, как печатает функция strftime() с форматирующей строкой %m/%d/%y. %k Эквивалент %Н. %l Эквивалент %I. %r Считывает время так, как печатает функция strftime() с форматирующей строкой %I:%М:%S %p. %R Считывает время так, как печатает функция strftime() с форматирующей строкой %Н:%М. %T Считывает время так, как печатает функция strftime() с форматирующей строкой %Н:%М:%S. %y Считывает год в пределах двадцатого столетия. Допустимы значения только от 0 до 99, поскольку к ним добавляется число 1900. %Y Считывает полный год. Применяйте, по возможности, этот формат вместо %у для того, чтобы избежать "проблемы 2000-го года".
Функция strptime() возвращает указатель на символ в s — символ, находящийся за последним прочитанным во время разбора.
Функция strptime(), к сожалению, не определена ни в ANSI/ISO, ни в POSIX, что ограничивает ее переносимость.
18.1.3. Ограничения, связанные со временем
В 32-разрядных системах Linux, как и в большинстве систем Unix, переменная time_t является целым числом со знаком длиной 32 бита. Это означает, что в 10:14:07 вечера 18 января (четверг) 2038 года она переполнится. Поэтому время 10:14:08 вечера 18 января (четверг) 2038 года будет представлено как 3:45:52 вечера 13 декабря (пятница) 1901 года. Как видите, система Linux не проявляет "проблему 2000-го года" (поскольку используются собственные библиотеки времени), однако с ней связана "проблема 2038-го года".