Linux программирование в примерах - Арнольд Роббинс
Шрифт:
Интервал:
Закладка:
static const char *const days[] = { /* Как ранее */ };
time_t now;
struct tm curtime; /* Структура, а не указатель */
time(&now); /* Получить текущее время */
curtime = *gmtime(&now); /* Разложить его и скопировать данные */
printf("Day of the week: %sn", days[curtime.tm_wday]);
/* Проиндексировать и напечатать, использовать . , а не -> */
Поле tm_isdst указывает, действует ли в настоящий момент летнее время (DST) Значение 0 означает, что DST не действует, положительное значение означает, что действует, а отрицательное значение — что информация о DST недоступна. (Стандарт С намеренно неконкретен, указывая лишь нулевое, положительное и отрицательное значения; это дает возможность большей свободы при реализации.)
6.1.3. Форматирование даты и времени
Примеры в предыдущем разделе показали, как поля в struct tm могли бы быть использованы в качестве индексов символьных строк для вывода информативных значений даты и времени. Хотя можно было бы написать собственный код, использующий такие массивы для форматирования даты и времени, стандартные процедуры облегчают работу
6.1.3.1. Простое форматирование времени: asctime() и ctime()
Две первые стандартные процедуры, перечисленные ниже, выводят данные в фиксированном формате:
#include <time.h> /* ISO С */
char *asctime(const struct tm *tm);
char *ctime(const time_t *timep);
Как и в случае с gmtime() и localtime(), asctime() и ctime() возвращают указатели на статические буфера, которые могут быть перезаписаны после каждого вызова. Более того, эти две процедуры возвращают строки в одном и том же формате. Они отличаются лишь видом принимаемых аргументов, asctime() и ctime() должны использоваться тогда, когда все, что вам нужно, это простые сведения о дате и времени.
#include <stdio.h>
#include <time.h>
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", а не "%sn", как можно было бы ожидать.
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("%sn", 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 Локальный часовой пояс или отсутствие символов, если сведения о часовом поясе недоступны %% Простой %Локаль (locale) является способом описания местной специфики, принимая во внимание такие вещи, как язык, кодировка символов и значения по умолчанию для форматирования дат, времени, денежных сумм и т.д. Мы будем иметь с ними дело в главе 13 «Интернационализация и локализация». Пока достаточно понять, что результаты strftime() для одной и той же форматирующей строки могут быть разными в зависимости от настроек текущей локали.