Местное время для системы определяется файлом часового пояса /etc/localtime, который часто ссылается на один из файлов в каталоге /usr/share/zoneinfo.
Формат файлов часовых поясов задокументирован на странице руководства tzfile(5). Файлы часовых поясов создаются с помощью zic(8), компилятора информации о часовых поясах. С помощью команды zdump можно вывести текущее время для указанных файлов часовых поясов.
Указание часового пояса для программы
Чтобы указать часовой пояс при выполнении программы, переменной среды TZ присваивается значение в виде строки, содержащей символ двоеточия (:), за которым следует одно из названий часовых поясов, определенное в /usr/share/zoneinfo. Установка часового пояса автоматически влияет на функции ctime(), localtime(), mktime() и strftime().
Для получения текущей установки часового пояса в каждой из этих функций применяется функция tzset(3), которая инициализирует три глобальные переменные:
char *tzname[2]; /* Название часового пояса и альтернативного часового пояса
с учетом действия режима летнего времени */
int daylight; /* Ненулевое значение при наличии альтернативного
часового пояса с учетом действия режима летнего времени */
long timezone; /* Разница в секундах между UTC и местным [поясным] временем */
Функция tzset() сначала проверяет значение переменной среды TZ. Если значение для нее не установлено, часовой пояс инициализируется значением по умолчанию, определенным в файле часового пояса /etc/localtime. Если переменная TZ определена и имеет значение, которое не может соответствовать файлу часового пояса, или если оно представляет собой пустую строку, тогда используется UTC. Для переменной среды TZDIR (нестандартное GNU-расширение) может быть установлено имя каталога, в котором требуется вести поиск информации о часовом поясе вместо исходного каталога /usr/share/zoneinfo.
Эффект использования переменной TZ можно увидеть, запустив на выполнение программу, показанную в листинге 10.4. При первом запуске будет виден вывод, соответствующий исходному часовому поясу системы (центральноевропейского времени, CET). При втором запуске будет указан часовой пояс для Новой Зеландии, где в заданное время года действует режим летнего времени и местное время опережает CET на 12 часов.
$ ./show_time
ctime() of time() value is: Tue Feb 1 10:25:56 2011
asctime() of local time is: Tue Feb 1 10:25:56 2011
strftime() of local time is: Tuesday, 01 Feb 2011, 10:25:56 CET
$ TZ=":Pacific/Auckland"./show_time
ctime() of time() value is: Tue Feb 1 22:26:19 2011
asctime() of local time is: Tue Feb 1 22:26:19 2011
strftime() of local time is: Tuesday, 01 February 2011, 22:26:19 NZDT
Листинг 10.4. Демонстрация эффекта часовых поясов и локалей
time/show_time.c
#include <time.h>
#include <locale.h>
#include "tlpi_hdr.h"
#define BUF_SIZE 200
int
main(int argc, char *argv[])
{
time_t t;
struct tm *loc;
char buf[BUF_SIZE];
if (setlocale(LC_ALL, "") == NULL)
errExit("setlocale"); /* Использование в преобразовании настроек локали */
t = time(NULL);
printf("ctime() of time() value is: %s", ctime(&t));
loc = localtime(&t);
if (loc == NULL)
errExit("localtime");
printf("asctime() of local time is: %s", asctime(loc));
if (strftime(buf, BUF_SIZE, "%A, %d %B %Y, %H:%M:%S %Z", loc) == 0)
fatal("strftime returned 0");
printf("strftime() of local time is: %s\n", buf);
exit(EXIT_SUCCESS);
}
time/show_time.c
В SUSv3 определяются два основных способа установки значения для переменной среды TZ. Как уже было рассмотрено, значение TZ может быть установлено в виде последовательности символов, содержащей двоеточие и строку. Эта строка идентифицирует часовой пояс в том виде, который присущ конкретной реализации, как правило, в виде путевого имени файла, содержащего описание часового пояса. (В Linux и в некоторых других реализациях UNIX в этом случае допускается не ставить двоеточие, но в SUSv3 это не указывается; из соображений портируемости двоеточие нужно ставить всегда.)
Еще один метод установки значения для TZ полностью указан в SUSv3. Согласно ему, переменной TZ присваивается срока следующего вида: