Настройки локализации управляют работой множества разнообразных GNU/Linux-утилит, а также многих функций в библиотеке glibc. Среди них функции strftime() и strptime() (см. подраздел 10.2.3), о чем свидетельствуют результаты, полученные от strftime() при выполнении программы из листинга 10.4:

$ LANG=de_DE./show_time Немецкая локаль

ctime() of time() value is: Tue Feb 1 12:23:39 2011

asctime() of local time is: Tue Feb 1 12:23:39 2011

strftime() of local time is: Dienstag, 01 Februar 2011, 12:23:39 CET

Следующий код демонстрирует, что LC_TIME имеет преимущество перед LANG:

$ LANG=de_DE LC_TIME=it_IT./show_time Немецкая и итальянская локали

ctime() of time() value is: Tue Feb 1 12:24:03 2011

asctime() of local time is: Tue Feb 1 12:24:03 2011

strftime() of local time is: martedì, 01 febbraio 2011, 12:24:03 CET

А этот код показывает, что LC_ALL имеет преимущество перед LC_TIME:

$ LC_ALL=fr_FR LC_TIME=en_US./show_time Французская и американская (США) локали

ctime() of time() value is: Tue Feb 1 12:25:38 2011

asctime() of local time is: Tue Feb 1 12:25:38 2011

strftime() of local time is: mardi, 01 février 2011, 12:25:38 CET

10.5. Обновление системных часов

Теперь рассмотрим два интерфейса, обновляющих системные часы: settimeofday() и adjtime(). Прикладными программами они используются довольно редко (поскольку обычно системное время поддерживается с помощью средств вроде демона сервиса точного времени Network Time Protocol), и к тому же им нужно, чтобы вызывающий процесс был привилегированным (CAP_SYS_TIME).

Системный вызов settimeofday() является обратным функции gettimeofday() (рассмотренной в разделе 10.1): он присваивает календарному времени системы значение, соответствующее количеству секунд и микросекунд, заданное в структуре timeval, указатель на которую находится в аргументе tv.

#define _BSD_SOURCE

#include

int settimeofday(const struct timeval *tv, const struct timezone *tz);

Возвращает при успешном завершении 0 или –1 при ошибке

Как и в случае с gettimeofday(), использование аргумента tz утратило актуальность, и в качестве его значения нужно указывать NULL.

Точность до микросекунд в поле v.tv_usec не означает наличие такой же точности в управлении системными часами, поскольку точность у часов может быть ниже одной микросекунды.

Хотя системный вызов settimeofday() в SUSv3 не определен, он широко доступен во многих других реализациях UNIX.

В Linux также предоставляется системный вызов stime(), предназначенный для установки системных часов. Разница между settimeofday() и stime() состоит в том, что последний вызов позволяет установить новое календарное время с точностью всего лишь в одну секунду. Как и в случае с time() и gettimeofday(), причина существования как stime(), так и settimeofday() имеет исторические корни: последний, задающий более точное значение вызов был добавлен в версии 4.2BSD.

Резкие изменения системного времени, связанные с вызовами settimeofday(), могут плохо влиять на приложения (например, на make(1), систему управления базами данных, использующую метки времени, или на файлы журналов, использующие метки времени). Поэтому при внесении незначительных изменений в установки времени (в пределах нескольких секунд) практически всегда предпочтительнее задействовать библиотечную функцию adjtime(), заставляющую системные часы постепенно выйти на требуемое значение.

#define _BSD_SOURCE

#include

int adjtime(struct timeval *delta, struct timeval *olddelta);

Возвращает при успешном завершении 0 или –1 при ошибке

Аргумент delta указывает на структуру timeval, определяющую количество секунд и микросекунд, на которое нужно изменить время. При положительном значении время добавляется к системным часам небольшими порциями каждую секунду до тех пор, пока не будет добавлено требуемое значение. При отрицательном значении delta ход часов замедляется в том же режиме.

Скорость изменения в Linux/x86-32 составляет одну секунду за каждые 2000 секунд (или 43,2 секунды за день).

Может получиться так, что вызов функции adjtime() придется на момент, когда предыдущее изменение показания часов не завершилось. В таком случае объем оставшегося неизмененного времени возвращается в timeval-структуру olddelta. Если это значение нас не интересует, для аргумента olddelta нужно указать NULL. И наоборот, если нас интересуют только сведения о текущем объеме невыполненной коррекции времени и мы не намереваемся изменять значение, в качестве аргумента delta можно указать NULL.

Несмотря на то что в SUSv3 функция adjtime() не указана, она доступна в большинстве реализаций UNIX.

Перейти на страницу:

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