Выбрать главу

int main(void) {

 time_t now;

 time(&now);

 printf("%s", ctime(& now));

}

После запуска эта программа выводит результат в виде: 'Thu May 22 15:44:21 2003'. Завершающий символ конца строки включен в результат. Точнее, возвращаемое значение указывает на массив из 26 символов, как показано на рис. 6.1.

Рис. 6.1. Возвращаемая функциями ctime() и asctime() строка

Значительная часть старого кода Unix полагается на тот факт, что значения в возвращенной строке имеют фиксированную позицию. При использовании этих функций помните, что они включают завершающий символ конца строки. Поэтому наш небольшой пример программы использует для printf() простую форматирующую строку "%s", а не "%s\n", как можно было бы ожидать.

ctime() устраняет необходимость шага вызова localtime(); в сущности, это эквивалентно

time_t now;

char *curtime;

time(&now);

curtime = asctime(localtime(&now));

6.1.3.2. Сложное форматирование времени: strftime()

Хотя часто достаточно использования asctime() и ctime(), у них есть также и ограничения:

• Формат вывода фиксирован. Нет способа изменить порядок элементов.

• В вывод не включаются сведения о часовом поясе.

• В выводе используются сокращенные названия месяца и дня.

• В выводе используются английские названия месяцев и дней.

По этим причинам C89 ввело стандартную библиотечную процедуру strftime():

#include <time.h> /* ISO С */

size_t strftime(char *s, size_t max, const char *format,

 const struct tm *tm);

strftime() сходна с sprintf(). Ее аргументы следующие:

char *s

Буфер для форматированной строки.

size_t max

Размер буфера.

const char *format

Форматирующая строка.

const struct tm *tm

Указатель на struct tm, представляющий разложенное время, которое надо отформатировать.

Форматирующая строка содержит символы букв, смешанные о описателями преобразования, указывающими, что должно быть помещено в строку, такими, как полное имя дня недели, час в соответствии с 24-часовым или 12-часовым циклом, наличие указателей am или p.m[64], и т.д. (Вскоре будут приведены примеры.)

Если всю строку можно отформатировать с использованием не более max символов, возвращаемое значение представляет собой число символов, помещенных в s, не включая завершающий нулевой байт. В противном случае, возвращаемое значение ноль. В последнем случае содержание s «неопределенно». Следующий простой пример дает представление об использовании strftime():

#include <stdio.h>

#include <time.h>

int main(void) {

 char buf[100];

 time_t now;

 struct tm *curtime;

 time(&now);

 curtime = localtime(&now);

 (void)strftime(buf, sizeof buf,

  "It is now %A, %B %d, %Y, %I:%M %p", curtime);

 printf("%s\n", buf);

 exit(0);

}

После запуска эта программа выводит что-то типа:

It is now Thursday, May 22, 2003, 04:15 PM

В табл. 6.2 предоставлен полный список описателей преобразования, их возможные альтернативные представления и их значения. Вдобавок стандарт C99 добавил к списку дополнительные описатели; новые для C99 описатели помечены символом √.

Таблица 6.2. Описатели преобразования формата strftime()

Описатель C99 Значение
%a Локальное сокращенное название дня недели.
%A Локальное полное название дня недели.
%b Локальное сокращенное название месяца.
%B Локальное полное название месяца.
%c, %Ec Локальное «подходящее» представление даты и времени
%C, %EC Век (00–99)
%d, %Od День месяца (01–31)
%D То же, что %m/%d/%y
%e, %Oe День месяца. Одна цифра дополняется пробелом (1–31).
%F То же, что и %Y-%m-%d (формат даты ISO 8601)
%g Две последние цифры, основанной на неделе года (00–99).
%G Основанный на неделе год ISO 8601
%h То же, что и %b
%H, %OH Час в 24-часовом цикле (00–23)
%I, %OI Час в 12-часовом цикле (01–12)
%j День года (001–366)
%m, %Om Месяц в виде числа (01–12).
%M, %OM Минута в виде числа (00–59)
%n Символ конца строки ('\n')
%p Локальное обозначение a.m./p.m.
%r Локальное время в 12-часовом цикле
%R Тоже, что и %H:%M
%S, %OS Секунда в виде числа (00–60)
%t Символ табуляции ('\t')
%T То же, что и %H:%M:%S (формат ISO 8601).
%u, %Ou Число дня недели ISO 8601, понедельник = 1 (1–7).
%U, %OU Номер недели, первое воскресенье является первым днем недели 1 (00–53)
%V, %OV Номер недели ISO 8601 (01–53)
%w, %Ow День недели как число, воскресенье = 0 (0–6).
%W, %OW Номер недели, первый понедельник является первым днем недели 1 (00–53)
%x, %Ex Локальное «подходящее» представление даты
%X, %EX Локальное «подходящее» представление времени.
%y, %Ey, %Oy Две последние цифры года (00–99)
%Y, %EY Год как число.
%Z Локальный часовой пояс или отсутствие символов, если сведения о часовом поясе недоступны
%% Простой %
вернуться

64

a.m. — от ante meridiem (до полудня), p.m. — от post meridiem (пополудни), американская система обозначения 12-часового цикла времени суток. — Примеч. перев.