Чтение онлайн

на главную - закладки

Жанры

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

Вызов

time(0)
возвращает
time_t
, представляющее временной интервал от зависящего от реализации начала отсчета (обычно 0:00:00 1 января 1970 года) до текущего момента.

Ошибка 2038 года

Так как

time_t
может представлять интервалы времени длиной в 68 лет, а многие реализации для представления текущего времени в качестве начала отсчета используют 1970 год, в большинстве популярных реализаций C++ невозможно представлять даты и времена после 2038 года. Это означает, что если программисты не предпримут мер предосторожности,
то в 2038 году большая часть программного обеспечения перестанет работать.

Наиболее удобное представление текущих даты и времени можно получить, преобразовав их с помощью функций

localtime
или
gmtime
в структуру
tm
. Структура
tm
содержит целочисленные поля, показанные в примере 5.2.

Пример 5.2. Содержимое структуры tm

struct tm {

 int tm_sec; // секунды в минуте от 0 до 61 (60 и 61 для секунд координации)

 int tm_min; // минуты в часе от 0 до 59

 int tm_hour; // часы в сутках от 0 до 23

 int tm_mday; // день месяца от 0 до 31

 int tm_mon; // месяц года от 0 до 11

 int tm_year; // год после 1900

 int tm_wday; // дней после воскресенья

 int tm_yday; // дней после 1-го января

 int tm_isdst; // часы летнего времени

};

При использовании функции

gmtime
не забудьте проверить ее возвращаемое значение. Если компьютер, на котором выполняется код, не имеет определенной локальной временной зоны (часового пояса), функция
gmtime
не сможет вычислить время UTC и вернет 0. Если передать 0 в функцию
asctime
, то результатом будет неопределенное поведение.

Функции

localtime
,
gmtime
и
asctime
возвращают указатели на статически размещенные в памяти объекты. Это более эффективно для библиотеки, не означает, что последующие вызовы будут изменять значение этих объектов. Код в примере 5.3 показывает, как это может привести к неожиданным эффектам.

Пример 5.3. Подводные камни использования asctime

void f {

 char* x = asctime(localtime(time(0)));

 wait_for_15_seconds; // выполняет длительную задачу обработки

 asctime(localtime(time(0)));

 cout << x << endl; // печатает текущее время, а не то что 15 секунд назад.

}

5.2. Форматирование даты/времени в виде строки

Проблема

Требуется преобразовать дату и/или время в строковый формат

Решение

Используйте шаблон класса

time_put
из заголовочного файла
<locale>
, как показано в примере 5.4.

Пример 5.4. Форматирование строки даты/времени

#include <iostream>

#include <cstdlib>

#include <ctime>

#include <cstring>

#include <string>

#include <stdexcept>

#include <iterator>

#include <sstream>

using namespace std;

ostream& formatDateTime(ostream& out, const tm& t, const char* fmt) {

 const time_put<char>& dateWriter = use_facet<time_put<char> >(out.getloc);

 int n = strlen(fmt);

 if (dateWriter.put(out, out, ' ', &t, fmt, fmt + n).failed) {

throw runtime_error("невозможно
отформатировать дату и время");

 }

 return out;

}

string dateTimeToString(const tm& t, const char* format) {

 stringstream s;

 formatDateTime(s, t.format);

 return s.str;

}

tm now {

 time_t now = time(0);

 return *localtime(&now);

}

int main {

 try {

string s = dateTimeToString(now, "%A %B, %d %Y %I:%M%p");

cout << s << endl;

s = dateTimeToString(now, "%Y-%m-%d %H:%M:%S);

cout << s << endl;

 } catch(...) {

cerr << "невозможно отформатировать дату и время" << endl;

return EXIT FAILURE.

 }

 return EXIT_SUCCESS;

}

Вывод программы из примера 5.4 будет содержать нечто подобное следующему, в зависимости от локальных настроек.

Sunday July, 24 2005 05:48PM 2005-07-24 17:48:11

Обсуждение

Метод

put
из
time_put
использует спецификатор форматирования строки, аналогичный строке формата функции С
printf
. Символы строки формата выводятся в выходной буфер по мере их появления при условии, что им не предшествует символ
%
. Символ, перед которым стоит
%
, — это спецификатор формата, который имеет специальное значение, приведенное в табл. 5.1. Спецификаторы формата также поддерживают модификаторы, такие как целое число, указывающее длину поля, как в
%4B
.

Поделиться:
Популярные книги

Лолита

Набоков Владимир Владимирович
Проза:
классическая проза
современная проза
8.05
рейтинг книги
Лолита

Я подарю тебе ребёнка

Малиновская Маша
Любовные романы:
современные любовные романы
6.25
рейтинг книги
Я подарю тебе ребёнка

Убивать чтобы жить 3

Бор Жорж
3. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 3

Небо для Беса

Рам Янка
3. Самбисты
Любовные романы:
современные любовные романы
5.25
рейтинг книги
Небо для Беса

Сердце Дракона. Том 11

Клеванский Кирилл Сергеевич
11. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
6.50
рейтинг книги
Сердце Дракона. Том 11

Печать мастера

Лисина Александра
6. Гибрид
Фантастика:
попаданцы
технофэнтези
аниме
фэнтези
6.00
рейтинг книги
Печать мастера

Идеальный мир для Лекаря 19

Сапфир Олег
19. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 19

Калибр Личности 1

Голд Джон
1. Калибр Личности
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Калибр Личности 1

Идеальный мир для Лекаря 2

Сапфир Олег
2. Лекарь
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 2

Волчья воля, или Выбор наследника короны

Шёпот Светлана
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Волчья воля, или Выбор наследника короны

Вечный. Книга I

Рокотов Алексей
1. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга I

Спасение 6-го

Уолш Хлоя
3. Парни из школы Томмен
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Спасение 6-го

Ротмистр Гордеев

Дашко Дмитрий Николаевич
1. Ротмистр Гордеев
Фантастика:
фэнтези
попаданцы
альтернативная история
5.00
рейтинг книги
Ротмистр Гордеев

Нечто чудесное

Макнот Джудит
2. Романтическая серия
Любовные романы:
исторические любовные романы
9.43
рейтинг книги
Нечто чудесное