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.