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

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 Полное название месяца (например, May (май)) c Полные дата и время d День месяца (01-31) H Час (00-23) I Час (01-12) j День года (001-366) m Месяц (01-12) M Минуты (00-59) p Признак AM/PM S Секунды, включая до двух секунд координации U Номер недели (00-53), причем неделя 1 начинается в первое воскресенье w День недели (0-6), где 0 — это воскресенье W Номер недели (00-53), причем неделя 1 начинается в первый понедельник x Дата в формате MM/DD/YY X Время в формате HH/MM/SS и 24-часовыми часами y Год текущего столетия (00-99) Y Год Z Сокращение временной зоны (часового пояса), или пустая строка, если зона неизвестна

Библиотека Boost date_time, обсуждаемая в дальнейших рецептах, не содержит возможностей форматирования, предлагаемых time_put. Для удобства пример 5.5 содержит несколько процедур, преобразующих классы даты/времени Boost в формат структуры tm, так что вы можете использовать процедуры time_put.

Пример 5.5. Преобразование из классов даты/времени Boost в структуру tm

using boost::gregorian;

using boost::posix_time;

void dateToTmAux(const date& src, tm& dest) {

 dest.tm_mday = src.day();

 dest tm_year = src.year() - 1900;

 dest.tm_mon = src.month() - 1;

}

void ptimeToTmAux(const ptime& src, tm& dest) {

 dest.tm_sec = src.seconds();

 dest.tm_min = st.minutes();

 dest.tm_hour = src.hours();

 dateToTmAux(src.date(), dest);

}

tm ptimeToTm(const ptime& t) {

 tm ret = tm();

 ptimeToTmAux(t.ret);

 return ret;

}

Смотри также

Рецепт 13.3.