Функции localtime
, gmtime
и asctime
возвращают указатели на статически размещенные в памяти объекты. Это более эффективно для библиотеки, не означает, что последующие вызовы будут изменять значение этих объектов. Код в примере 5.3 показывает, как это может привести к неожиданным эффектам.
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.
#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
.
Спецификатор | Описание |
---|---|
a | Сокращенное название дня недели (например, Mon (пн)) |
A | Полное название дня недели (например, Monday (понедельник)) |
b | Сокращенное название месяца (например, Dec (дек)) |
B |