Я хотел бы преобразовать int
дата как:
20111201
в string
:
01DEC2011
Существует ли быстрое преобразование формата даты, встроенное в C ++ (или, возможно, системная команда bash, которую я могу выполнить вместо этого), чтобы сделать это, или я застрял, переключаясь на все месяцы?
Вы можете использовать strptime для преобразования вашей строки в struct tm, а затем использовать strftime для ее переформатирования:
#include <ctime>
#include <iostream>
#include <sstream>
int main()
{
std::ostringstream date1;
date1 << 20111201;
struct tm tm;
strptime(date1.str().c_str(), "%Y%m%d", &tm);
char date2[10];
strftime(date2, sizeof(date2), "%d%b%Y", &tm);
std::cout << date1.str() << " -> " << date2 << std::endl;
}
Выход:
20111201 -> 01Dec2011
Просто нужно преобразовать декабрь в верхний регистр, если это необходимо.
Не используйте Bash здесь. Нужно использовать Boost в C ++ по нескольким причинам, чем я могу перечислить здесь, но в конечном итоге это будет так же быстро, как и большинство других решений, с которыми вы столкнетесь, и если ваша функциональность абсолютно не критична по времени, она выиграет ». в любом случае это не имеет большого значения.
Кроме того, он будет гораздо более гибким и обслуживаемым, чем все те дрянные маленькие жестко запрограммированные процедуры преобразования дат, с которыми вы всегда сталкиваетесь.
Следующий код будет делать то, что вы хотите.
#include <iostream>
#include <sstream>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/algorithm/string.hpp>
using namespace boost::gregorian;
using namespace std;
int main(int argc, char **argv)
{
int dateIn = 20111201;
// Read the date in from ISO format as an int.
ostringstream ss;
ss << dateIn;
date d(from_undelimited_string( ss.str() ));
// Set the output format
date_facet *fct = new date_facet("%d%b%Y"); // [1]
locale loc = locale(locale::classic(), fct);
// Render the date as a string;
ss.str("");
ss.imbue(loc);
ss << d;
string dateOut( ss.str() );
boost::to_upper( dateOut );
cout << dateOut << endl;
}
Это дает следующий вывод:
01DEC2011
Просто изменив формат строки "%d%b%Y"
по ссылке [1]
изменится на другой формат вывода, но помните, что я также преобразовал его в верхний регистр.
Там нет ничего встроенного, так как этот формат для дат
относительно редко. Самое простое решение здесь было бы
разбить дату на год, месяц, день, используя %
а также /
операторы (например, месяц value / 100 % 100
), затем отформатируйте
три значения обычно, используя std::ostream
и глядя вверх
дата в таблице. (Это, очевидно, потребует некоторой ошибки
проверка, поскольку не все целые значения дают действительные даты.)
Новый ответ на старый вопрос. Этот ответ трафик через C ++ 11/14 <chrono>
библиотека вместо C tm
или же boost::date_time
, В остальном это очень похоже на существующие ответы. Это требует этого бесплатная библиотека с открытым исходным кодом для разбора и форматирования.
#include "tz.h"#include <iostream>
#include <locale>
#include <sstream>
int
main()
{
auto date1 = 20111201;
std::stringstream stream;
stream.exceptions(std::ios::failbit);
stream << date1;
std::chrono::system_clock::time_point tp;
date::parse(stream, "%Y%m%d", tp);
auto str = date::format("%d%b%Y", tp);
auto& ct = std::use_facet<std::ctype<char>>(std::locale::classic());
ct.toupper(&str.front(), &str.back()+1);
std::cout << str << '\n';
}
Я включил stream.exceptions(std::ios::failbit);
с шумом обнаружить недействительные «целочисленные даты». И я включил старый код C ++ 98 для преобразования строки в верхний регистр ( locale
танец в конце).
01DEC2011
Одним из преимуществ использования современной библиотеки даты / времени C ++ является простота внесения изменений. Например, что если теперь вам нужно анализировать метку времени не с точностью до дня, а с точностью до миллисекунды? Вот как это можно сделать:
auto date1 = 20111201093357.275L;
std::stringstream stream;
stream.exceptions(std::ios::failbit);
stream << std::fixed << date1;
std::chrono::system_clock::time_point tp;
date::parse(stream, "%Y%m%d%H%M%S", tp);
auto str = date::format("%d%b%Y %T", tp);
auto& ct = std::use_facet<std::ctype<char>>(std::locale::classic());
ct.toupper(&str.front(), &str.back()+1);
std::cout << str << '\n';
какие выводы:
01DEC2011 09:33:57.275000
Или, возможно, эти метки времени происходят из Остров Чатем у побережья Новой Зеландии и они нужны вам в UTC. Просто добавьте одну строку после parse
:
tp = date::locate_zone("Pacific/Chatham")->to_sys(tp);
И теперь вывод:
30NOV2011 19:48:57.275000
Принятие во внимание произвольных часовых поясов и точностью до секунды в настоящее время выходит за рамки возможностей всех других библиотек C ++.