6.1.4. Преобразование разложенного времени в time_t
6.1.4. Преобразование разложенного времени в time_t
Получение от системы значений «секунд с начала Эпохи» просто; именно так даты и времена хранятся в индексах и возвращаются с помощью time() и stat(). Эти значения также легко оценивать на равенство или посредством < и > для простых тестов раньше/позже.
Однако, с датами, введенными людьми, не так легко работать. Например, многие версии команды touch позволяют предусмотреть дату и время, в которое touch должна установить время модификации или доступа к файлу (с помощью utime(), как было описано в разделе 5.5.3 «Изменение отметок времени: utime()»).
Преобразование даты, введенной человеком, в значение time_t трудно: надо принять во внимание високосные годы, учесть часовые пояса и т.д. Поэтому стандарт C89 ввел функцию mktime():
#include <time.h> /* ISO С */
time_t mktime(struct tm *tm);
Для использования mktime() укажите в struct tm соответствующие значения — год, месяц, день и т.д. Если вы знаете, действовало ли для данной даты летнее время, установите соответствующим образом поле tm_isdst: 0 для «нет» и положительное значение для «да». В противном случае, используйте отрицательное значение для «не знаю». Поля tm_wday и tm_yday игнорируются.
mktime() предполагает, что struct tm представляет локальное время, не UTC. Она возвращает значение time_t, представляющее переданные дату и время, или (time_t)(-1), если данные дата/время не могут быть правильно представлены. После успешного возвращения все значения struct tm выверены на попадание в правильные диапазоны, a tm_wday и tm_yday также корректно установлены. Вот простой пример:
1 /* ch06-echodate.c --- демонстрирует mktime(). */
2
3 #include <stdio.h>
4 #include <time.h>
5
6 int main(void)
7 {
8 struct tm tm;
9 time_t then;
10
11 printf("Enter a Date/time as YYYY/MM/DD HH:MM:SS : ");
12 scanf("%d/%d/%d %d:%d:%d",
13 &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
14 &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
15
16 /* Проверка ошибок значений для краткости опущена. */
17 tm.tm_year -= 1900;
18 tm.tm_mon--;
19
20 tm.tm_isdst = -1; /* He знаю о летнем времени */
21
22 then = mktime(&tm);
23
24 printf("Got: %s", ctime(&then));
25 exit(0);
26 }
В строке 11 запрашиваются дата и время, а в строках 12–14 соответствующие значения считываются. (В коде изделия возвращаемые scanf() значения должны проверяться.) Строки 17 и 18 компенсируют различную базу для лет и месяцев соответственно. Строка 20 указывает, что мы не знаем, представляют ли данные дата и время летнее время. Строка 22 вызывает mktime(), а строка 24 выводит результат преобразования. После компилирования и запуска мы видим, что это работает:
$ ch06-echodate
Enter a Date/time as YYYY/MM/DD HH:MM:SS : 2003/5/25 19:07:23
Got: Sun May 25 19:07:23 2003