Настройки локализации управляют работой множества разнообразных 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
Теперь рассмотрим два интерфейса, обновляющих системные часы: settimeofday() и adjtime(). Прикладными программами они используются довольно редко (поскольку обычно системное время поддерживается с помощью средств вроде демона сервиса точного времени
Системный вызов settimeofday() является обратным функции gettimeofday() (рассмотренной в разделе 10.1): он присваивает календарному времени системы значение, соответствующее количеству секунд и микросекунд, заданное в структуре timeval, указатель на которую находится в аргументе tv.
#define _BSD_SOURCE
#include
int settimeofday(const struct timeval *
Возвращает при успешном завершении 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 *
Возвращает при успешном завершении 0 или –1 при ошибке
Аргумент delta указывает на структуру timeval, определяющую количество секунд и микросекунд, на которое нужно изменить время. При положительном значении время добавляется к системным часам небольшими порциями каждую секунду до тех пор, пока не будет добавлено требуемое значение. При отрицательном значении delta ход часов замедляется в том же режиме.
Скорость изменения в Linux/x86-32 составляет одну секунду за каждые 2000 секунд (или 43,2 секунды за день).
Может получиться так, что вызов функции adjtime() придется на момент, когда предыдущее изменение показания часов не завершилось. В таком случае объем оставшегося неизмененного времени возвращается в timeval-структуру olddelta. Если это значение нас не интересует, для аргумента olddelta нужно указать NULL. И наоборот, если нас интересуют только сведения о текущем объеме невыполненной коррекции времени и мы не намереваемся изменять значение, в качестве аргумента delta можно указать NULL.
Несмотря на то что в SUSv3 функция adjtime() не указана, она доступна в большинстве реализаций UNIX.