STRFTIME(3) | Руководство программиста Linux | STRFTIME(3) |
strftime - форматирование даты и времени
#include <time.h>
size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);
Функция strftime() преобразует время из структуры tm в соответствии с определённым форматом format и помещает результат в символьный массив s размера max. Структура tm определена в <time.h>. Смотрите также ctime(3).
Формат представляет собой строку с null в конце, в которой могут содержаться специальные символьные последовательности, называемые определителями преобразования, каждая из которых состоит из символа '%' и ещё одного символа, называемого символом определителя преобразования. Все остальные символьные последовательности являются обычными символьными последовательностями.
Символы из обычных символьных последовательностей (включая байт null) копируются как есть из format в s. Однако, символы из определителей преобразования заменяются согласно списку, представленному ниже. В этом списке также показаны использованные поля из структуры tm.
Некоторые определения преобразования могут быть изменены с помощью указания перед символом определителя преобразования модификатора E или O, который указывает на необходимость использования альтернативного формата. Если альтернативный формат или определение не существует в текущей локали, то поведение будет таким же как если бы проводилось не изменённое преобразование. (SU) В Single UNIX Specification упомянуты %Ec, %EC, %Ex, %EX, %Ey, %EY, %Od, %Oe, %OH, %OI, %Om, %OM, %OS, %Ou, %OU, %OV, %Ow, %OW, %Oy, где модификатор O означает использование альтернативных численных символов (например, римские цифры), а модификатор E отражает альтернативное представление, зависящее от текущей локали.
Предоставляя строку результата с завершающим байтом null, не превышающую max байт, функция strftime() возвращает количество символов (без учёта конечного байта null), помещённых в массив s. Если длина строки результата (включая завершающий байт null) превысила бы max байт, то strftime() возвращает 0, а содержимое массива будет неопределенным.
Заметим, что возвращаемое значение 0 не всегда означает ошибку. Например, во многих локалях %p представляет собой пустую строку. Пустая строка format считается пустой строкой.
Используются переменные окружения TZ и LC_TIME.
Описание терминов данного раздела смотрите в attributes(7).
Интерфейс | Атрибут | Значение |
strftime() | Безвредность в нитях | MT-Safe env locale |
SVr4, C89, C99. Большинство этих определителей поддерживаются стандартом ANSI C (не помечен), Single UNIX Specification (помечен как SU), пакетом часовых поясов Олсона (Olson) (помечен как TZ) и glibc (помечен как GNU), кроме %+, которое не поддерживается в glibc2. С другой стороны, в glibc2 есть несколько дополнительных расширений. В POSIX.1 есть ссылка только на ANSI C; в POSIX.2 описание date(1) содержит несколько расширений, которые можно применить и к strftime(). Преобразование %F есть в C99 и POSIX.1-2001.
В SUSv2 определитель %S позволяет использовать диапазон от 00 до 61, что даёт теоретическую возможность включать в минуту двойную високосную секунду (такой минуты ещё никогда не было).
Определители %G, %g и %V заменяются значениями, вычисленными из года на основе недели, который определяется стандартом ISO 8601. В этой системе недели начинаются с понедельника и нумеруются с 01 до 52 или 53. Неделя 1 — это первая неделя, где четыре или более дней находятся в новом году (иначе говоря, неделя 01 это первая неделя года, в которой есть четверг; или неделя с 4 января). Если три или менее дней первой календарной недели выпадают на новый год, то согласно системе счёта недель ISO 8601 эти дни являются частью недели 53 предыдущего года. Например, 1 января 2010 это пятница, то есть только три дня этой календарной недели выпадают на 2010. То есть согласно системе недель ISO 8601 эти три дня являются частью недели 53 (%V) 2009 года (%G); неделя 01 по ISO 8601 для 2010 года начинается с понедельника 4 января 2010 года.
В glibc есть несколько расширений определений преобразования (эти расширения не входят в POSIX.1-2001, но в некоторых других системах есть подобные возможности). Между символом '%' и символом определителя преобразования может быть указан flag и поле width (и они указываются до модификаторов E или O).
Допускаются следующие символьные флаги:
После флага (возможно отсутствующего) может быть указан десятичный определитель ширины. Если реальный размер поля меньше чем эта ширина, то строка результата дополняется (слева) до указанной ширины.
Если строка результата превысила бы max байт, значение errno не изменяется. Это делает невозможным отличить данную ошибку от случая, когда для строки format обоснованно создаётся строка результата нулевой длины. В POSIX.1-2001 не определены какие-либо значения errno для strftime().
Некоторые дефектные версии gcc(1) выдают сообщение об использовании %c: warning: `%c' yields only last 2 digits of year in some locales. Естественно, программистам предлагается использовать %c, что даёт предпочтительное представление даты и времени. Каждый, кто встречает подобного вида странные путаницы, обходит эту проблему gcc(1). Относительно понятный способ — это добавить промежуточную функцию
size_t my_strftime(char *s, size_t max, const char *fmt, const struct tm *tm) { return strftime(s, max, fmt, tm); }
В настоящее время, у gcc(1) есть параметр -Wno-format-y2k, который отключает предупреждение, поэтому такой способ решения больше не нужен.
Формат даты согласно RFC 2822 (в английской локали с %a и %b)
"%a, %d %b %Y %T %z"
Формат даты согласно RFC 822 (в английской локали с %a и %b)
"%a, %d %b %y %T %z"
Представленную ниже программу можно использовать для экспериментов с strftime().
Несколько примеров строк результата, созданных strftime() в реализации glibc:
$ ./a.out '%m' Строка результата: "11" $ ./a.out '%5m' Строка результата: "00011" $ ./a.out '%_5m' Строка результата: " 11"
#include <time.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { char outstr[200]; time_t t; struct tm *tmp; t = time(NULL); tmp = localtime(&t); if (tmp == NULL) { perror("localtime"); exit(EXIT_FAILURE); } if (strftime(outstr, sizeof(outstr), argv[1], tmp) == 0) { fprintf(stderr, "strftime вернула 0"); exit(EXIT_FAILURE); } printf("Строка результата: \"%s\"\n", outstr); exit(EXIT_SUCCESS); }
date(1), time(2), ctime(3), setlocale(3), sprintf(3), strptime(3)
2019-03-06 | GNU |