Литмир - Электронная Библиотека
A
A

/* Для краткости проверка ошибок опущена */

time_t now, then, some_time;

time(&now); /* Получить текущее время */

then = now - (6L * 31 * 24 * 60 * 60); /* Примерно 6 месяцев назад */

/* ...установить какое-нибудь время, например, через stat()... */

if (some_time < then)

 /* более 6 месяцев назад */

else

 /* менее 6 месяцев назад */

Однако, поскольку переносимый код может потребоваться запустить на не-POSIX системах, существует функция

difftime()
для вычисления разницы между двумя значениями времени. Тот же самый тест с использованием
difftime()
можно было бы написать таким способом:

time_t now, some_value;

const double six_months = 6.0 * 31 * 24 * 60 * 60;

time(&now); /* Получить текущее время */

/* ...установить какое-нибудь время, например, через stat()... */

if (difftime(now, some_time) >= six_months)

 /* более 6 месяцев назад */

else

 /* менее 6 месяцев назад */

Возвращаемым типом

difftime()
является
double
, поскольку
time_t
может также содержать доли секунд. На системах POSIX он всегда представляет целые секунды.

В обоих предыдущих примерах обратите внимание на использование типизированных констант, чтобы форсировать выполнение вычислений с нужным математическим типом:

6L
в первом случае для целых
long
, 6.0 во втором случае для чисел с плавающей точкой

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 {

 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 tm
называют разложенным временем (broken-down time), поскольку значение
time_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.) Конечно, отсчет их с нуля также практичен; поскольку массивы С отсчитываются с нуля, использование этих значений в качестве индексов тривиально:

65
{"b":"576259","o":1}