Функции 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.

Tабл. 5.1. Спецификаторы формата даты/времени

Спецификатор Описание
a Сокращенное название дня недели (например, Mon (пн))
A Полное название дня недели (например, Monday (понедельник))
b Сокращенное название месяца (например, Dec (дек))
B
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату