Для получения текущего времени, вычисления разницы между двумя значениями time_t
, преобразования значений time_t
в более удобное представление и форматирования обоих представлений в виде символьных строк существуют различные функции. Вдобавок, представление даты и времени можно преобразовать обратно в time_t
, доступна также ограниченная информация по часовым поясам.
Отдельный набор функций предоставляет доступ к текущему времени с разрешением, большим чем одна секунда. Функции работают с предоставлением двух различных значений, времени в виде секунд с начала Эпохи и числа микросекунд в текущей секунде. Эти функции описаны далее в разделе 14.3.1 «Время в микросекундах: gettimeofday()
».
6.1.1. Получение текущего времени: time()
и difftime()
Системный вызов time()
получает текущие дату и время; difftime()
вычисляет разницу между двумя значениями time_t
:
#include
time_t time(time_t *t);
double difftime(time_t time1, time_t time0);
time()
возвращает текущее время. Если параметр t
не равен NULL
, переменная, на которую указывает t
, также заполняется значением текущего времени. Функция возвращает (time_t)(-1)
, если была ошибка, устанавливая errno
.
Хотя ISO С не указывает, чем является значение time_t
, POSIX определяет, что оно представляет время в секундах. Поэтому это предположение является обычным и переносимым. Например, чтобы посмотреть, что значение времени представляет отметку в прошлом шесть месяцев назад или позже, можно использовать код, подобный этому:
/* Для краткости проверка ошибок опущена */
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
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; /* секунды */