Библиотека time языка C. Работа со временем
Создано: 25.09.2025
В языке Си есть библиотека для работы со временем (в том числе датами), функции и типы данных которой подключаются с помощью заголовочного файла time.h
. Одной из функций мы уже пользовались для генерации псевдослучайных чисел. Однако сразу после того урока изучать библиотеку времени было бы затруднительно, так как в ней используются указатели и структуры.
Вспомним, что с помощью функции time()
мы получали целое число, значение которого зависело от постоянно меняющегося времени. Это время соответствует текущему системному времени в секундах, прошедших с 1 января 1970 г (в некоторых ОС возможно с 1900 г). Кроме того, тип данный того, что возвращает time()
, ‒ не совсем целое число, а time_t
, описанный в заголовочном файле time.h
. Однако в зависимости от ОС time_t
определен как int
или long int
. Следовательно, формат вывода значения будет %d
или %ld
.
Ранее мы передавали в time()
значение NULL
, получали текущее время, которое сразу передавали в функцию srand()
, чтобы задать зерно для генерации случайных чисел. Теперь мы будем присваивать текущее время переменной, имеющей тип time_t
.
С другой стороны, time()
можно вызывать по-другому. Если передать не NULL
, а адрес переменной типа time_t
, то функция запишет в эту переменную текущее время. То есть функция и возвращает данные (всегда), и меняет значение аргумента (только если передан адрес).
#include <stdio.h> #include <time.h> int main() { time_t var1; var1 = time(NULL); printf("var1 = %ld", var1); getchar(); time_t var2; time(&var2); printf("var2 = %ld", var2); getchar(); time_t var3, var4; var4 = time(&var3); printf("var3 = %ld\n", var3); printf("var4 = %ld\n", var4); }
Пример выполнения программы:
var1 = 1758675472 var2 = 1758675475 var3 = 1758675479 var4 = 1758675479
В примере getchar()
используется для выполнения задержки между вызовами time()
. Чтобы увидеть разные значения, перед нажатием Enter пользователю следует немного выжидать. Две последние переменные в любом случае будут содержать одинаковые значения, так как они являются результатом одного и того же вызова time()
.
Время, выраженное числом в секундах, мало о чем нам говорит. Но оно удобно для сравнений и вычисления промежутков времени:
time_t start, finish; int answer; start = time(NULL); printf("Сколько будет 34 - 58?\n"); do { scanf("%d", &answer); } while (answer != -24); finish = time(NULL); printf("Вы решали %.0f сек.\n", difftime(finish, start));
Пример выполнения:
Сколько будет 34 - 58? 80 56 -24 Вы решали 9 сек.
Функция difftime()
вычисляет разницу между двумя объектами time_t
. Если сначала передать меньшее значение, то возвращаемое ею число будет отрицательным. Вместо difftime()
можно просто вычесть значение одной переменной из другой, однако в этом случае тип данных будет длинным целым, а не double
.

Если все же мы хотим увидеть дату, которая была получена в секундах, в "человеческом" виде, проще всего воспользоваться функцией ctime()
, которая вернет строку, содержащую информацию о времени и дате. Передавать этой функции надо адрес переменной типа time_t
, а не ее значение.
time_t var1 = time(NULL); printf("%s", ctime(&var1));
Пример выполнения:
Wed Sep 24 04:56:09 2025
Если мы хотим выводить данные не в таком жестко заданном формате или нам нужны отдельные компоненты времени (например, только время или дата) для выполнения с ними в дальнейшем различных операций, то нет другого пути, как преобразовать значение time_t
в структурный тип struct tm
.
Сделать это можно с помощью двух функций ‒ localtime()
и gmtime()
. Обе возвращают указатель на данные типа struct tm
, но в первом будут характеристики локального времени, во втором ‒ по UTC.
time_t var = time(NULL); struct tm *varL = localtime(&var); printf("%d\n", varL->tm_hour); printf("%s", asctime(varL)); struct tm *varG = gmtime(&var); printf("%d\n", varG->tm_hour); printf("%s", asctime(varG));
Пример выполнения:
5 Wed Sep 24 05:07:29 2025 2 Wed Sep 24 02:07:29 2025
В примере мы выводим значение только поля tm_hour
структуры. Все поля: tm_sec
, tm_min
, tm_hour
, tm_mday
, tm_mon
(месяцы с 0 до 11), tm_year
(годы отсчитываются, начиная с 1900), tm_wday
(день недели, 0 ‒ воскресенье), tm_yday
(номер дня, начиная с начала года, 0 ‒ первое значение), tm_isdst
(признак летнего времени: положительное значение ‒ да, 0 ‒ нет, отрицательное значение ‒ неизвестно).
Также в примере выше используется функция asctime()
, которая является аналогом ctime()
, но применяемым по отношению к struct tm
, а не time_t
. Обратите внимание, что переменная, которая передается в asctime()
уже содержит адрес (является указателем).
Более широкие возможности у функции strftime()
, которая позволяет выводить дату в произвольно заданном формате. В качестве аргументов она принимает строку для записи данных с указанием ее размера, строку со спецификаторами форматов характеристик времени, указатель на структуру типа struct tm
откуда данные берутся.
time_t t = time(NULL); struct tm *st = localtime(&t); char output[30]; strftime(output, sizeof(output), "%T %D", st); printf("%s\n", output); strftime(output, sizeof(output), "%H:%M:%S %d-%m-%Y", st); printf("%s\n", output);
Пример выполнения:
06:31:39 09/24/25 06:31:39 24-09-2025
Все спецификации форматов времени, которых очень много, можно посмотреть в той или иной документации (например, в Bash с помощью команды man strftime
).
Нередко требуется дату получить с ввода, сохранить в программе и использовать для выполнения тех или иных операций с датами. Здесь мы сталкиваемся с обратной задачей: есть строка, требуется ее привести к типу struct tm
или time_t
. Для таких случаев есть функция strptime()
. Чтобы она работала, необходимо определить макрос, содержащийся в константе _XOPEN_SOURCE
(возможно не для всех ОС).
#define _XOPEN_SOURCE #include <stdio.h> #include <time.h> int main() { struct tm t; char date[30]; printf("Введите дату в формате h:m dd-mm-yyyy\n"); fgets(date, sizeof(date), stdin); strptime(date, "%H:%M %d-%m-%Y", &t); printf("%d\n", t.tm_hour); printf("%d\n", t.tm_min); printf("%d !\n", t.tm_sec); // ! printf("%d !\n", t.tm_wday); // ! printf("%d\n", t.tm_mday); printf("%d\n", t.tm_mon); printf("%d\n", t.tm_year); }
Пример выполнения:
Введите дату в формате h:m dd-mm-yyyy 4:08 24-09-2025 4 8 32768 ! 3 ! 24 8 125
Обратите внимание, что, хотя мы не задаем день недели, он правильно записывается в соответствующее поле структуры (tm_wday
). Однако поле tm_sec
видимо принимает максимально возможное для себя значение. Чтобы его изменить, следует присвоить значение явно.
Помимо рассмотренных в уроке функций в библиотеке time.h
имеется функция clock()
, которая не принимает аргументы и возвращает значение типа clock_t
(аналог long int
). Это значение обозначает время, но измеряемое не в секундах, а в тактах процессора. Значение отсчитывается от начала выполнения программы. Количество тактов в секунде можно узнать с помощью константы CLOCKS_PER_SEC
.
#include <stdio.h> #include <stdlib.h> #include <time.h> #define N 10000 int main() { clock_t start = clock(); for (int i = 1; i <= N; i++) rand(); clock_t finish = clock(); printf("%ld\n", finish - start); printf("%ld\n", CLOCKS_PER_SEC); }
Пример выполнения:
791 1000000
- Заполните поля структуры типа
struct tm
с ввода. Чтобы увидеть получившуюся дату, выведите ее с помощьюasctime()
. - Получите значение текущего системного времени, приведите его к структурному типу. Передвиньте дату вперед на 10 дней (возможно потребуется поменять месяц или даже год). Используя функцию
mktime()
, которая выполняет конвертациюstruct_tm
вtime_t
, преобразуйте время обратно в секунды. Найдите разницу с исходным значением и убедитесь, что она соответствует 10 дням (в 1 дне 86400 секунд).