C ++ конвертировать форматы даты

Я хотел бы преобразовать int дата как:

20111201

в string:

01DEC2011

Существует ли быстрое преобразование формата даты, встроенное в C ++ (или, возможно, системная команда bash, которую я могу выполнить вместо этого), чтобы сделать это, или я застрял, переключаясь на все месяцы?

2

Решение

Вы можете использовать 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

Просто нужно преобразовать декабрь в верхний регистр, если это необходимо.

4

Другие решения

Не используйте 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] изменится на другой формат вывода, но помните, что я также преобразовал его в верхний регистр.

2

Там нет ничего встроенного, так как этот формат для дат
относительно редко. Самое простое решение здесь было бы
разбить дату на год, месяц, день, используя % а также /
операторы (например, месяц value / 100 % 100), затем отформатируйте
три значения обычно, используя std::ostreamи глядя вверх
дата в таблице. (Это, очевидно, потребует некоторой ошибки
проверка, поскольку не все целые значения дают действительные даты.)

0

Новый ответ на старый вопрос. Этот ответ трафик через 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 ++.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector