Функция strftime
Функция форматированной записи ремени и даты.
Функция strftime преобразует время, представленное в виде структуры типа struct tm, на которую указывает аргумент t, в текстовую строку str. Выходная текстовая строка формируется в соответствии с форматом, на который указывает аргумент str_form. В конце строки помещается нулевой символ (признак конца строки).
size_t strftime (char *str, size_t maxsize, const char *str_form, const struct tm * t);
где str – указатель на строку в которую будет помещен результат преобразования; maxsize – длина строки, на которую указывает аргумент str; str_form – формат преобразования даты и времени; t – структура, содержащая дату и время для преобразования.
Если дата и время успешно преобразованы и длинна полученной строки не превышает maxsize, то функция возвращает длину полученной строки, иначе возвращается 0, при этом содержимое строки, на которую указывает аргумент str, будет не определенно.
Строка, содержащая формат преобразования, может содержать как обычные символы, так и спецификаторы (аналогично формату функции printf, но с другими значениями). Обычные символы копируются в выходную строку без изменения, спецификаторы заменяются на соответствующие данные из структуры, на которую указывает аргумент t. При преобразовании используются следующие спецификаторы: %a – сокращенное название дня недели (например, Sun).
%a – аббревиатура названия дня недели (например, Sun).
%A - полное название дня недели (например, Sunday).
%b - сокращенное название месяца (например, Dec).
%B - полное название месяца (например, December).
%c - дата и время (например, Dec 2 06:55:15 1979).
%d - день месяца (например, 02).
%H - час в 24-часовом диапазоне (например, 06).
%I - час в 12-часовом диапазоне (например, 06).
%j - день года начиная с 001 (например, 335).
%m - месяц начиная с 01 (например, 12).
%M - минуты (например, 55).
%p - AM/PM индикатор, AM - означает до полудня, PM - после полудня (например, AM).
%S - секунды (например, 15).
%U - номер недели (с воскресенья до понедельника) в году, начиная с 00 (например, 48).
%w - номер дня недели, воскресенью соответствует 0 (например, 6).
%W - номер недели (с понедельника до воскресенья) в году, начиная с 00 (например, 47).
%x - дата (например, Dec 2 1979).
%X - время (например, 06:55:15).
%y - последние две цифры года (например, 79).
%Y - год (например, 1979).
%Z - часовой пояс (например, EST).
%% - символ процента %.
В примере ниже в консоль выводятся дата, день недели и время, полученные с помощью функции strftime.
#include <stdio.h>
#include <time.h>
int main (void)
{
long int s_time; // Переменная для системного времени
struct tm *m_time; // Указатель на структуру с локальным временем
char str_t[128]=""; // Строка для сохранения преобразованного времени
s_time = time(NULL); // Считываем системное время
m_time = localtime(&s_time); // Преобразуем системное время в локальное
strftime (str_t, 128, "Date: %x %A %X", m_time);
// Преобразуем локальное время в текстовую строку
printf ("%s\n", str_t); // Выводим строку в консоль
return 0;
}
При помощи функции strftime можно получить строку, аналогичную формату стоки возврата функции asctime. В этом случае необходимо использовать следующий формат: «%a %b %d %H:%M:%S %Y\n»
Для работы с датой в интерпретаторе shell используются команды date и cal. Примеры их вызова приведены на стр.14. Рекомендовано самостоятельно изучить форматы их вызова.
Интересно знать! Существует связанная с датой ошибка, известная как ошибка Y2K (YEAR 2 KILOS). С проблемой столкнулись на границе перехода веков, а именно при переходе с 31.12.1999 года в 01.01.2000 года. Дело в том, что программисты прошлого века не посчитали нужным выделить лишний байт под хранение года (а точнее первых двух его цифр), в результате 1999 год должен был смениться на 1900 (99->00). Сделано это было в далекие годы начала развития ЭВМ для повышения быстродействия работы программ и экономии памяти. Особую обеспокоенность вызывали стратегически-важные объекты, сбои в работе которых могли привести к отказу жизнеобеспечивающих систем, непредсказуемой работе военно-ракетных комплексов, взрыву атомных реакторов и пр. Над решением проблемы работали тысячи математиков и программистов во всем мире, написаны миллионы патчей, были потрачены сотни миллионов долларов, написаны сотни книг. В результате, проблема была благополучно решена (в каждой стране и компании по-своему), глобальных проблем перехода мир не ощутил.
ПОДГОТОВКА К ЛАБОРАТОРНОЙ РАБОТЕ
Постановка задачи
Разработать программу, которая определяет день недели по любой заданной дате календаря от 12.12.1901 до 19.01.2038. Требуемая дата должна передаваться программе в формате DD.MM.YYYY одним аргументом командной строки ее вызова. Латинская аббревиатура дня недели должна отображаться строкой стандартного вывода. Код возврата программы должен содержать порядковый номер дня недели или (−1) при ошибке формата даты в аргументе командной строки ее вызова.
ТЕКСТ ПРОГРАММЫ
#include <time.h> // заголовок файл для времени и даты
#include <stdio.h> // заголовок стандартного ввода-вывода
int main(int argc, char* argv[]) // Основная функция программы
{
int day; // число месяца
int mon; // номер месяца
int year;
struct tm drec; // структура даты
struct tm start, end;
start.tm_mday = 12;
start.tm_mon = 11;
start.tm_year = 1;
start.tm_sec = start.tm_min = start.tm_hour = start.tm_isdst = 0;
end.tm_mday = 19;
end.tm_mon = 0;
end.tm_year = 138;
end.tm_sec = end.tm_min = end.tm_hour = end.tm_isdst = 0;
char week[4]; // аббревиатура дня недели
if(argc > 1) // проверка числа аргументов
{
if (sscanf(argv[1], "%d%*[.]%d%*[.]%d", &day, &mon, &year)<3)
{
printf ("Incorrect format\n");
return(-1);
}
// считывание аргумента командной строки
drec.tm_mday = day; // заполнение поля дня структуры drec
drec.tm_mon = mon - 1; // заполнение поля месяц структуры drec
drec.tm_year = year - 1900; // заполнение поля год структуры drec
drec.tm_sec = drec.tm_min = drec.tm_hour = drec.tm_isdst = 0;
if ((mktime(&start)>mktime(&drec))||(mktime(&end)<mktime(&drec)))
{
printf ("Input date is not between 12.12.1901 - 19.01.2038 \n");
return (-1);
}
strftime(week, 4, "%a", &drec); // получение и стандартный вывод аббревиатуры дня недели
puts(week);
return(drec.tm_wday); // возврат номера дня недели
}
return 0;
