Выбрать главу

Листинг 10.1. Извлечение и преобразование значений календарного времени

time/calendar_time.c

#include <locale.h>

#include <time.h>

#include <sys/time.h>

#include "tlpi_hdr.h"

#define SECONDS_IN_TROPICAL_YEAR (365.24219 * 24 * 60 * 60)

int

main(int argc, char *argv[])

{

time_t t;

struct tm *gmp, *locp;

struct tm gm, loc;

struct timeval tv;

t = time(NULL);

printf("Seconds since the Epoch (1 Jan 1970): %ld", (long) t);

printf(" (about %6.3f years)\n", t / SECONDS_IN_TROPICAL_YEAR);

if (gettimeofday(&tv, NULL) == -1)

errExit("gettimeofday");

printf(" gettimeofday() returned %ld secs, %ld microsecs\n",

(long) tv.tv_sec, (long) tv.tv_usec);

gmp = gmtime(&t);

if (gmp == NULL)

errExit("gmtime");

gm = *gmp; /* Сохранение локальной копии, так как содержимое, на которое указывает

*gmp, может быть изменено вызовом asctime() или gmtime() */

printf("Broken down by gmtime():\n");

printf(" year=%d mon=%d mday=%d hour=%d min=%d sec=%d", gm.tm_year,

gm.tm_mon, gm.tm_mday, gm.tm_hour, gm.tm_min, gm.tm_sec);

printf("wday=%d yday=%d isdst=%d\n", gm.tm_wday, gm.tm_yday, gm.tm_isdst);

gm.tm_isdst);

locp = localtime(&t);

if (locp == NULL)

errExit("localtime");

loc = *locp; /* Сохранение локальной копии */

printf("Broken down by localtime():\n");

printf(" year=%d mon=%d mday=%d hour=%d min=%d sec=%d",

loc.tm_year, loc.tm_mon, loc.tm_mday,

loc.tm_hour, loc.tm_min, loc.tm_sec);

printf("wday=%d yday=%d isdst=%d\n\n", loc.tm_wday, loc.tm_yday, loc.tm_isdst);

printf("asctime() formats the gmtime() value as: %s", asctime(&gm));

printf("ctime() formats the time() value as: %s", ctime(&t));

printf("mktime() of gmtime() value: %ld secs\n", (long) mktime(&gm));

printf("mktime() of localtime() value: %ld secs\n", (long) mktime(&loc));

exit(EXIT_SUCCESS);

}

time/calendar_time.c

Функция strftime() предоставляет нам более тонкую настройку управления при преобразовании разделенного календарного времени в печатный вид.

Функция strftime(), которой в аргументе timeptr передается указатель на структуру, содержащую разделенное время, возвращает соответствующую строку, завершаемую нулевым байтом, в буфер, заданный аргументом outst. В этой строке хранятся и дата и время.

#include <time.h>

size_t strftime(char *outstr, size_t maxsize, const char *format,

const struct tm *timeptr);

Возвращает при успешном завершении количество байтов, помещенных в строку, на которую указывает outstr (исключая завершающий нулевой байт), или 0 при ошибке

Строка, возвращенная в буфер, на который указывает outstr, отформатирована в соответствии со спецификаторами, заданными аргументом format. Аргумент maxsize указывает максимальное пространство, доступное в буфере, заданном аргументом outstr. В отличие от ctime() и asctime() функция strftime() не включает в окончание строки символ новой строки (кроме того, что включается в спецификацию формата, указываемую аргументом format).

В случае успеха функция strftime() возвращает количество байтов, помещенных в буфер, на который ссылается outstr, исключая завершающий нулевой байт. Если общая длина получившейся строки, включая завершающий нулевой байт, станет превышать количество байтов, заданное в аргументе maxsize, функция strftime() возвратит 0, чтобы показать ошибку; в этом случае содержимое буфера, на который указывает outstr, станет неопределенным.

Аргумент format, используемый при вызове strftime(), представляет собой строку по типу той, что задается в функции printf(). Последовательности, начинающиеся с символа процента (%), являются спецификаторами преобразования, которые заменяются различными компонентами даты и времени в соответствии с символом, следующим за символом процента. Предусмотрен довольно обширный выбор спецификаторов преобразования, часть компонентов которого перечислена в табл. 10.1. (Полный перечень можно найти на странице руководства strftime(3).) За исключением особо оговариваемых, все эти спецификаторы преобразования стандартизированы в SUSv3.

Спецификаторы %U и %W выводят номер недели в году. Номера недель, выводимые с помощью %U, исчисляются из расчета, что первая неделя, начиная с воскресенья, получает номер 1, а предшествующая ей неполная неделя получает номер 0. Если воскресенье приходится на первый день года, то неделя с номером 0 отсутствует и последний день года приходится на неделю под номером 53. Нумерация недель, выводимых с помощью %W, работает точно так же, но вместо воскресенья в расчет берется понедельник.

Зачастую в книге нам придется выводить текущее время в различных демонстрационных программах. Для этого мы предоставляем функцию currTime(), которая возвращает строку с текущим временем, отформатированным функцией strftime() при заданном аргументе format.

#include "curr_time.h"

char *currTime(const char *format);

Возвращает при успешном завершении указатель на статически размещенную строку или NULL при ошибке

Реализация функции currTime() показана в листинге 10.2.