Таблица 10.1. Отдельные спецификаторы преобразования для strftime()
Спецификатор — Описание — Пример
%% — Символ % — %
%a — Сокращенное название дня недели — Tue
%A — Полное название дня недели — Tuesday
%b, %h — Сокращенное название месяца — Feb
%B — Полное название месяца — February
%c — Дата и время — Tue Feb 1 21:39:46 2011
%d — День месяца (две цифры, от 01 до 31) — 01
%D — Дата в американском формате (то же самое, что и %m/%d/%y) — 02/01/11
%e — День месяца (два символа) — _1
%F — Дата в формате ISO (то же самое, что и %Y-%m-%d) — 2011-02-01
%H — Час (24-часовой формат, две цифры) — 21
%I — Час (12-часовой формат, две цифры) — 09
%j — День года (три цифры, от 001 до 366) — 032
%m — Месяц в виде десятичного числа (две цифры, от 01 до 12) — 02
%M — Минута (две цифры) — 39
%p — AM/PM (до полудня/после полудня) — PM
%P — am/pm (GNU-расширение) — pm
%R — Время в 24-часовом формате (то же самое, что и %H:%M) — 21:39
%S — Секунда (от 00 до 60) — 46
%T — Время (то же самое, что и %H:%M:%S) — 21:39:46
%u — Номер дня недели (от 1 до 7, Понедельник = 1) — 2
%U — Номер недели, начинающейся с воскресенья (от 00 до 53) — 05
%w — Номер дня недели (от 0 до 6, воскресенье = 0) — 2
%W — Номер недели, начинающейся с понедельника (от 00 до 53) — 05
%x — Дата (локализированная версия) — 02/01/11
%X — Время (локализированная версия) — 21:39:46
%y — Последние две цифры года — 11
%Y — Год в формате четырех цифр — 2011
%Z — Название часового пояса — CET
Листинг 10.2. Функция, возвращающая строку с текущим временем
time/curr_time.c
#include <time.h>
#include "curr_time.h" /* Объявление определяемых здесь функций */
#define BUF_SIZE 1000
/* Возвращает строку, содержащую текущее время, отформатированное в сооответствии
со спецификацией в 'format' (спецификаторы на странице руководства strftime(3)).
Если 'format' имеет значение NULL, в качестве спецификатора мы используем "%c"
(что дает дату и время, как для ctime(3), но без завершающего символа новой строки).
При ошибке возвращается NULL. */
char *
currTime(const char *format)
{
static char buf[BUF_SIZE]; /* Нереентерабельная */
time_t t;
size_t s;
struct tm *tm;
t = time(NULL);
tm = localtime(&t);
if (tm == NULL)
return NULL;
s = strftime(buf, BUF_SIZE, (format!= NULL)? format: "%c", tm);
return (s == 0)? NULL: buf;
}
time/curr_time.c
Преобразование из печатного вида в разделенное календарное время
Функция strptime() выполняет преобразование, обратное тому, которое делает функция strftime(). Она преобразует строку в виде даты и времени в разделенное календарное время (время, разбитое на компоненты).
#define _XOPEN_SOURCE
#include <time.h>
char *strptime(const char *str, const char *format, struct tm *timeptr);
Возвращает при успешном завершении указатель на следующий необработанный символ в str или NULL при ошибке
Функция strptime() использует спецификацию, заданную в аргументе format, для разбора строки в формате «дата плюс время», указанной в аргументе str. Затем она помещает результат преобразования в разделенное календарное время в структуру, на которую указывает аргумент timeptr.
В случае успеха strptime() возвращает указатель на следующий необработанный символ в str. (Это пригодится, если строка содержит дополнительную информацию для обработки вызывающей программой.) Если полная строка формата не может быть подобрана, функция strptime() возвращает значение NULL, чтобы показать, что возникла ошибка.
Спецификация формата, заданная функцией strptime(), похожа на ту, что задается scanf(3). В ней содержатся следующие типы символов:
• спецификации преобразования, начинающиеся с символа процента (%);
• пробельные символы, соответствующие нулю или большему количеству пробелов во введенной строке;
• непробельные символы (отличающиеся от %), которые должны соответствовать точно таким же символам во введенной строке.
Спецификации преобразования похожи на те, которые задаются в функции strftime() (см. табл. 10.1). Основное отличие заключается в их более общем характере. Например, спецификаторы %a и %A могут принять название дня недели как в полной, так и в сокращенной форме, а %d или %e могут использоваться для чтения дня месяца, если он может быть выражен одной цифрой с ведущим нулем или без него. Кроме того, регистр символов игнорируется. Например, для названия месяца одинаково подходят May и MAY. Строка %% применяется для соответствия символу процента во вводимой строке. Дополнительные сведения можно найти на странице руководства strptime(3).
Реализация strptime(), имеющаяся в библиотеке glibc, не вносит изменений в те поля структуры tm, которые не инициализированы спецификаторами из аргумента format. Это означает, что для создания одной структуры tm на основе информации из нескольких строк, из строки даты и строки времени, мы можем воспользоваться серией вызовов strptime(). Хотя в SUSv3 такое поведение допускается, оно не является обязательным, и поэтому полагаться на них в других реализациях UNIX не стоит. В портируемом приложении, прежде чем вызвать strptime(), нужно обеспечить наличие в аргументах str и format входящей информации, которая установит все поля получаемой в итоге структуры tm, или же предоставить подходящую инициализацию структуры tm. В большинстве случаев достаточно задать всей структуре нулевые значения, используя функцию memset(). Но нужно иметь в виду, что значение 0 в поле tm_mday соответствует в glibc-версии и во многих других реализациях функции преобразования времени последнему дню предыдущего месяца. И наконец, следует учесть, что strptime() никогда не устанавливает значение имеющегося в структуре tm для аргумента tm_isdst.