Локаль (locale) является способом описания местной специфики, принимая во внимание такие вещи, как язык, кодировка символов и значения по умолчанию для форматирования дат, времени, денежных сумм и т.д. Мы будем иметь с ними дело в главе 13 «Интернационализация и локализация». Пока достаточно понять, что результаты
strftime()
для одной и той же форматирующей строки могут быть разными в зависимости от настроек текущей локали.
Версии, начинающиеся с
%E
и
%O
, предназначены для «альтернативного представления». В некоторых локалях есть несколько способов представления одних и тех же сведений; эти описатели предоставляют доступ к дополнительным представлениям. Если определенная локаль не поддерживает альтернативного представления,
strftime()
использует обычную версию.
Многие Unix-версии
date
дают возможность предоставить в командной строке форматирующую строку, начинающуюся с символа '
+
'. Затем
date
форматирует текущие дату и время и выводит в соответствии с форматирующей строкой:
$ <b>date + 'It is now %A, %B %d, %Y, %I:%M %p'</b>
It is now Sunday, May 25, 2003, 06:44 PM
Большинство новых описателей C99 происходит от таких существующих реализаций
date
Unix. Описатели
%n
и
%t
не являются в С абсолютно необходимыми, поскольку символы табуляции и конца строки могут быть помещены в строку непосредственно. Однако в контексте форматирующей строки
date
для командной строки они имеют больше смысла. Поэтому они также включены в спецификацию
strftime()
.
Стандарт ISO 8601 определяет (среди других вещей), как нумеруются недели в пределах года. В соответствии с этим стандартом недели отсчитываются с понедельника по воскресенье, а понедельник является днем недели 1, а не 0. Если неделя, в которой оказывается 1 января, содержит по крайней мере четыре дня нового года, она считается неделей 1. В противном случае, это последняя неделя предыдущего года с номером 52 или 53. Эти правила используются для вычислений описателей форматов
%g
,
%G
и
%V
. (Хотя ограниченным американцам, таким, как автор, эти правила могут показаться странными, они обычно повсюду используются в Европе.)
Многие из описателей стандартов дают результаты, специфичные для текущей локали. Вдобавок некоторые указывают, что они выдают «подходящее» представление для локали (например,
%x
). Стандарт C99 определяет значения для локали «С». Эти значения перечислены в табл. 6.3
Таблица 6.3. Значения локали «С» для определенных форматов
strftime()
Описатель | Значение |
%а
| Первые три символа %А . |
%А
| Один из дней Sunday, Monday, …, Saturday |
%b
| Первые три символа %В
|
%В
| Один из месяцев January, February, …, December |
%с
| То же, что и %а %b %е %T %Y
|
%p
| AM или PM |
%r
| То же, что и %I:%M:%S %p
|
%x
| То же, что и %m/%d/%y
|
%X
| То же, что и %T . |
%Z
| Определяется реализацией |
Должно быть очевидно, что
strftime()
предоставляет значительную гибкость и контроль над связанным с датой и временем выводом, во многом таким же образом, как
printf()
и
sprintf()
. Более того,
strftime()
не может переполнить буфер, поскольку она проверяет входной параметр размера, что делает ее более безопасной процедурой, чем
sprintf()
.
В качестве простого примера рассмотрим создание файлов журнала программы, когда каждый час создается новый файл. Имя файла должно включать дату и время создания:
/* Проверка ошибок для краткости опущена */
char fname[PATH_МАХ]; /* PATH_МАХ находится в <limits.h> */
time_t now;
struct tm *tm;
int fd;
time(&now);
tm = localtime(&now);
strftime(fname, sizeof fname, "/var/log/myapp.%Y-%m-%d-%H:%M", tm);
fd = creat(name, 0600);
...
Формат год-месяц-день-час-минута вызывает сортировку файлов в том порядке, в каком они были созданы.
ЗАМЕЧАНИЕ. Некоторые форматы данных более полезны, чем другие. Например, 12-часовое время двусмысленно, также, как чисто числовые форматы дат. (Что означает '
9/11
'? Это зависит от того, где вы живете) Сходным образом, годы из двух цифр также являются плохой мыслью. Используйте
strftime()
благоразумно
6.1.4. Преобразование разложенного времени в
time_t
Получение от системы значений «секунд с начала Эпохи» просто; именно так даты и времена хранятся в индексах и возвращаются с помощью
time()
и
stat()
. Эти значения также легко оценивать на равенство или посредством < и > для простых тестов раньше/позже.
Однако, с датами, введенными людьми, не так легко работать. Например, многие версии команды
touch
позволяют предусмотреть дату и время, в которое
touch
должна установить время модификации или доступа к файлу (с помощью
utime()
, как было описано в разделе 5.5.3 «Изменение отметок времени:
utime()
»).