Нейл Мэтью - Основы программирования в Linux стр 53.

Шрифт
Фон

Не думайте, что для хранения времени достаточно 32 битов. В системах UNIX и Linux, использующих 32-разрядный тип time_t, временное значение "будет превышено" в 2038 г. Мы надеемся, что к тому времени системы перейдут на тип time_t, содержащий более 32 битов. Недавнее широкое внедрение 64-разрядных процессоров превращает это практически в неизбежность.

#include <time.h>

time_t time(time_t *tloc);

Вы можете найти низкоуровневое значение времени, вызвав функцию time, которая вернет количество секунд с начала эпохи (упражнение 4.6). Она также запишет возвращаемое значение по адресу памяти, на который указывает параметр tloc, если он - непустой указатель.

Упражнение 4. Функция time

Далее для демонстрации функции time приведена простая программа envtime.c.

#include <time.h>

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

int main() {

int i;

time_t the_time;

for (i = 1; i <= 10; i++) {

the_time = time((time_t *)0);

printf("The time is %ld\n", the_time);

sleep(2);

}

exit(0);

}

Когда вы запустите программу, она будет выводить низкоуровневое значение времени каждые 2 секунды в течение 20 секунд.

$ ./anytime

The time is 1179643852

The time is 1179643854

The time is 1179643856

The time is 1179643858

The time is 1179643860

The time is 1179643862

The time is 1179643864

The time is 1179643866

The time is 1179643868

The time is 1179643870

Как это работает

Программа вызывает функцию time с пустым указателем в качестве аргумента, которая возвращает время и дату как количество секунд. Программа засыпает на две секунды и повторяет вызов time в целом 10 раз.

Использование времени и даты в виде количества секунд, прошедших с начала 1970 г., может быть полезно для измерения длительности чего-либо. Вы сможете сосчитать простую разность значений, полученных из двух вызовов функции time. Однако комитет, разрабатывавший стандарт языка ISO/ANSI С, в своих решениях не указал, что тип time_t будет применяться для определения произвольных интервалов времени в секундах, поэтому была придумана функция difftime, которая вычисляет разность в секундах между двумя значениями типа time_t и возвращает ее как величину типа double:

#include <time.h>

double difftime(time_t time1, time_t time2);

Функция difftime вычисляет разницу между двумя временными значениями и возвращает величину, эквивалентную выражениювремя1–время2, как число с плавающей точкой. В ОС Linux значение, возвращаемое функцией time, - это количество секунд, которое может обрабатываться, но для максимальной переносимости следует применять функцию difftime.

Для представления времени и даты в более осмысленном (с человеческой точки зрения) виде мы должны преобразовать значение времени в понятные время и дату. Для этого существуют стандартные функции.

Функция gmtime подразделяет низкоуровневое значение времени на структуру, содержащую более привычные поля:

#include <time.h>

struct tm *gmtime(const time_t timeval)

В структуре tm, как минимум, определены элементы, перечисленные в табл. 4.2.

Таблица 4.2

Элемент tmОписание
int tm_secСекунды, 0–61
int tm_minМинуты, 0–59
int tm_hourЧасы, 0–23
int tm_mdayДень в месяце, 1–31
int tm_monМесяц в году, 0–11 (January (январь) соответствует 0)
int tm_yearГоды, начиная с 1900 г.
int tm_wdayДень недели, 0–6 (Sunday (воскресенье) соответствует 0)
int tm_ydayДень в году, 0–365
int tm_isdstДействующее летнее время

Диапазон элемента tm_sec допускает появление время от времени корректировочной секунды или удвоенной корректировочной секунды.

Выполните упражнение 4.7.

Упражнение 4.7. Функция gmtime

Далее приведена программа gmtime.с, выводящая текущие время и дату с помощью структуры tm и функции gmtime.

#include <time.h>

#include <stdio.h>

#include <stdlib.h>

int main() {

struct tm *tm_ptr;

time_t the_time;

(void)time(&the_time);

tm_ptr = gmtime(&the_time);

printf("Raw time is %ld\n", the_time);

printf("gmtime gives:\n");

printf("date: %02d/%02d/%02d\n",

tm_ptr->tm_year, tm_ptr->tm_mon+1, tm_ptr->tm_mday);

printf("time: %02d:%02d:%02d\n",

tm_ptr->tm_hour, tm_ptr->tm_min, tm_ptr->tm_sec);

exit(0);

}

Выполнив эту программу, вы получите хорошее соответствие текущим времени и дате:

$ ./gmtime; date

Raw time is 1179644196

gmtime gives:

date: 107/05/20

time: 06:56:36

Sun May 20 07:56:37 BST 2007

Как это работает

Программа вызывает функцию time для получения машинного представления значения времени и затем вызывает функцию gmtime для преобразования его в структуру с удобными для восприятия значениями времени и даты. Она выводит на экран полученные значения с помощью функции printf. Строго говоря, выводить необработанное значение времени таким способом не следует, потому что наличие типа длинного целого не гарантировано во всех системах. Если сразу же после вызова функции gmtime выполнить команду date, можно сравнить оба вывода.

Но здесь у вас возникнет небольшая проблема. Если вы запустите эту программу в часовом поясе, отличном от Greenwich Mean Time (время по Гринвичу) или у вас действует летнее время, как у нас, вы заметите, что время (и, возможно, дата) неправильное. Все дело в том, что функция gmtime возвращает время по Гринвичу (теперь называемое Universal Coordinated Time (всеобщее скоординированное время) или UTC). Системы Linux и UNIX поступают так для синхронизации всех программ и систем в мире. Файлы, созданные в один и тот же момент в разных часовых поясах, будут отображаться с одинаковым временем создания. Для того чтобы посмотреть местное время, следует применять функцию localtime.

#include <time.h>

struct tm *localtime(const time_t *timeval);

Функция localtime идентична функции gmtime за исключением того, что она возвращает структуру, содержащую значения с поправками на местный часовой пояс и действующее летнее время. Если вы выполните программу gmtime, но замените все вызовы функции gmtime на вызовы localtime, в отчете программы вы увидите правильные время и дату.

Для преобразования разделенной на элементы структуры tm в общее внутреннее значение времени можно применить функцию mktime:

#include <time.h>

time_t mktime(struct tm *timeptr);

Ваша оценка очень важна

0
Шрифт
Фон

Помогите Вашим друзьям узнать о библиотеке

Похожие книги