Книга: Linux программирование в примерах

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

Оглавление книги


Генерация: 3.108. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз