Книга: Linux программирование в примерах
6.1.2. Разложение времени: gmtime() и localtime()
6.1.2. Разложение времени: gmtime()
и localtime()
На практике форма представления даты и времени в виде «секунд с начала эпохи» не является очень удобной, кроме очень простых сравнений. Самостоятельное вычисление компонентов времени, таких, как месяц, день, год и т.д., подвержено ошибкам, поскольку необходимо принять во внимание местный часовой пояс (возможно, с учетом перехода на летнее время), правильно вычислить високосные годы и пр. К счастью, две стандартные процедуры делают за вас эту работу:
#include <time.h> /* ISO С */
возвращает указатель на
struct tm *gmtime(const time_t *timep);
struct tm *localtime(const time_t *timep);
gmtime()struct tm
, которая представляет время UTC. localtime()
возвращает указатель на struct tm
, представляющий местное время, т.е. в расчет берутся текущий часовой пояс и переход на летнее время. На самом деле это «время для настенных часов», дата и время, которые были бы отображены на настенных или ручных часах. (Как это работает, обсуждается далее в разделе 6.1.5 «Получение сведений о часовом поясе».)
Обе функции возвращают указатель на struct tm
, которая выглядит следующим образом:
struct tm {
называют разложенным временем (broken-down time), поскольку значение
int tm_sec; /* секунды */
int tm_min; /* минуты */
int tm_hour; /* часы */
int tm_mday; /* день месяца */
int tm_mon; /* месяц */
int tm_year; /* год */
int tm_wday; /* день недели */
int tm_yday; /* день в году */
int tm_isdst; /* летнее время */
};
struct tmtime_t
«разложено» на свои составные части. Составные части, их диапазоны и значения показаны в табл. 6.1.
Таблица 6.1. Поля структуры tm
Член | Диапазон | Значение |
---|---|---|
tm_sec |
0–60 | Секунда минуты. Секунда 60 предусматривает пропущенные (leap) секунды. (В C89 был диапазон 0–61.) |
tm_min |
0–59 | Минута часа. |
tm_hour |
0–23 | Час дня |
tm_mday |
1–31 | День месяца |
tm_mon |
0–11 | Месяц года |
tm_year |
0–N | Год, начиная с 1900 г. |
tm_wday |
0–6 | День недели, воскресенье = 0 |
tm_yday |
0–365 | День года, 1 января = 0. |
tm_isdst |
<0, 0, >0 | Флаг летнего времени. |
Стандарт ISO С представляет большинство этих значений как «x
после y
». Например, tm_sec
является числом «секунд после минуты», tm_mon
«месяцев после января», tm_wday
«дней недели после воскресенья» и т.д. Это помогает понять, почему все значения начинаются с 0. (Единственным исключением, достаточно логичным, является tm_mday
, день месяца, имеющий диапазон 1–31.) Конечно, отсчет их с нуля также практичен; поскольку массивы С отсчитываются с нуля, использование этих значений в качестве индексов тривиально:
static const char *const days[] = { /* Массив имен дней */
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday",
};
time_t now;
struct tm *curtime;
time(&now); /* Получить текущее время */
curtime = gmtime(&now); /* Разложить его */
printf("Day of the week: %sn", days[curtime->tm_wday]);
/* Проиндексировать и вывести */
Как gmtime()
, так и localtime()
возвращают указатель на struct tm
. Указатель указывает на static struct tm
, содержащуюся в каждой процедуре, и похоже, что эти структуры struct tm
переписываются каждый раз, когда вызываются процедуры. Поэтому хорошая мысль сделать копию возвращенной struct
. Возвращаясь к предыдущему примеру.
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 недоступна. (Стандарт С намеренно неконкретен, указывая лишь нулевое, положительное и отрицательное значения; это дает возможность большей свободы при реализации.)
- Уменьшение времени, необходимого для резервного копирования и восстановления
- Ограничение времени ожидания для транзакций (Lock timeout)
- 7.12. Объективизация времени
- Квант времени
- Формула времени. Тайм-менеджмент на Outlook 2013
- 12.6. Сигналы реального времени
- Время от времени оптическая мышь начинает мигать. Она сломалась?
- B10. Функции даты и времени: ‹time.h›
- Влияние доказательств и затраченного времени
- Настройка даты и времени
- Разложение по стопкам
- 7.20. Извлечение даты и времени из строки