Программирование в стандарте POSIX

       

Опрос и установка показаний часов реального времени


Простейшим средством опроса и/или изменения текущих даты и времени является служебная программа date:

date [-u] [+формат] date [-u] ммддччмм[[вв]гг]

В первой форме утилита date выдает на стандартный вывод дату и время (по умолчанию - текущие), в соответствии с заданным форматом. Во второй форме date позволяет установить системные дату и время.

При наличии опции -u работа ведется без учета часового пояса, во всемирном времени (как если бы значением переменной окружения TZ была цепочка "UTC0"). Без этой опции учитывается значение TZ или, если таковое не установлено или пусто, принимается во внимание системное подразумеваемое значение.

Если в командной строке date задан аргумент, начинающийся со знака +, форматом вывода даты и времени управляет пользователь. Формат включает спецификаторы преобразований и прочие символы (последние выводятся без изменений). Спецификаторы преобразований начинаются со знака % и замещаются при выводе соответствующим значением.

Таблица 12.1. Спецификаторы преобразований

СпецификаторОписание
%aСокращенное название дня недели.
%AПолное название дня недели.
%b

Сокращенное название месяца.

%BПолное название месяца.
%cПринятое в данной языково-культурной среде представление даты и времени.
%CДве первые цифры четырехзначного номера года [00, 99].
%dНомер дня в месяце [01, 31].
%DДата в формате мм/дд/гг.
%eНомер дня в месяце [1, 31] в двухсимвольном поле с дополнением, при необходимости, пробела.
%hТо же, что %b.
%HНомер часа [00, 23].
%IНомер часа [01, 12].
%jНомер дня в году [001, 366].
%mНомер месяца [01, 12].
%M

Минуты [00, 59].

%nПеревод строки
%S

Секунды [00, 60].

%tТабуляция
%TВремя в формате чч:мм:сс.
%uНомер дня недели [1, 7] (единица соответствует понедельнику).
%UНомер недели в году [00, 53]. Первым днем недели считается воскресенье. Все дни нового года, предшествующие первому воскресенью, относятся к нулевой неделе.
%VНомер недели в году [01, 53]. Первым днем недели считается понедельник. Если первое января приходится на пятницу, субботу или воскресенье, конец недели формально относят к прошлому году, а первой считают следующую неделю.
%wНомер дня недели [0, 6] (ноль соответствует воскресенью).
%WНомер недели в году [00, 53]. Первым днем недели считается понедельник. Все дни нового года, предшествующие первому понедельнику, относятся к нулевой неделе.
%xПринятое в данной языково-культурной среде представление даты.
%XПринятое в данной языково-культурной среде представление времени.
%yДве младшие цифры номера года [00, 99].
%YЧетырехзначный номер года.
%ZИмя часового пояса.
%%Знак процента.
<
Чтобы установить текущие дату и время, необходимо, чтобы система допускала данное действие, а у процесса были соответствующие привилегии.

Во второй форме вызова утилиты date первая пара букв м обозначает номер месяца, дд - номер дня в месяце, чч - часы, мм - минуты, ввгг - год. Если две первые цифры года опущены, то диапазон [69, 99] трактуется как [1969, 1999], а [00, 68] - как [2000, 2068]. Если год не указан, имеется в виду текущий.

Приведем несколько примеров употребления служебной программы date.

Вывод в подразумеваемом формате, используемом командой date без аргументов, может выглядеть так:

Fri Dec 26 17:48:02 MSK 2003

Опция -u повлияет на вывод следующим образом:

Fri Dec 26 14:48:05 UTC 2003



Команда

date '+Дата: %d.%m.%Y%nВремя: %H:%M:%S'

выдаст примерно следующее:

Дата: 26.12.2003 Время: 17:49:15

Для сдвига показаний системных часов на один час вперед можно воспользоваться shell-процедурой, показанной в листинге 12.1 (предполагается, что ее выполняют днем при наличии соответствующих привилегий).

moda=`date +%m%d` ho=$((`date +%H` + 1)) mi=`date +%M` date ${moda}${ho}${mi}

Листинг 12.1. Пример использования служебной программы date. (html, txt)



С функцией time() ассоциирована функция difftime(), вычисляющая ( в виде значения типа double) разность в секундах между двумя моментами времени (time1 - time0, см. листинг 12.3).

#include <time.h> double difftime (time_t time1, time_t time0);

Листинг 12.3. Описание функции difftime().

Узнать текущее время с большей точностью позволяет функция gettimeofday() (см. листинг 12.4).

#include <sys/time.h> int gettimeofday (struct timeval *restrict tp, void *restrict tzp);

Листинг 12.4. Описание функции gettimeofday().

Согласно стандарту POSIX-2001, описанная в заголовочном файле <sys/time.h> структура timeval содержит по крайней мере следующие поля.

time_t tv_sec; /* Секунды */ suseconds_t tv_usec; /* Микросекунды */

Функция gettimeofday() записывает текущее время, выраженное в секундах и микросекундах от начала отсчета, в структуру типа timeval, на которую указывает аргумент tp. Указатель tzp должен быть пустым.

Впрочем, микросекунды - это еще на предел точности, а опрос системных часов - не предел общности. В необязательную часть стандарта POSIX-2001, регламентирующую работу с таймерами, входят функции, позволяющие опросить и установить показания заданных часов, а также узнать их разрешающую способность (см. листинг 12.5).

#include <time.h> int clock_getres (clockid_t clock_id, struct timespec *res); int clock_gettime (clockid_t clock_id, struct timespec *tp); int clock_settime (clockid_t clock_id, const struct timespec *tp);

Листинг 12.5. Описание функций опроса характеристик и установки часов.

Структура timespec отличается от timeval тем, что вместо микросекунд хранит наносекунды:

time_t tv_sec; /* Секунды */ long tv_nsec; /* Наносекунды */

Функция clock_getres() позволяет опросить разрешающую способность часов с заданным идентификатором и поместить результат в структуру, на которую указывает аргумент res.

Функция clock_gettime() записывает в аналогичную структуру текущие показания заданных часов.

Наконец, функция clock_settime() устанавливает заданные часы на основании значений полей структуры типа timespec, на которую указывает аргумент tp.


Содержание раздела