int
次のように日付を変換したいと思います。
20111201
にstring
:
2011年12月1日
これを行うためにC++に組み込まれた高速の日付形式変換(または代わりに実行できるbashシステムコマンド)がありますか?
int
次のように日付を変換したいと思います。
20111201
にstring
:
2011年12月1日
これを行うために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
必要に応じて、Dec を大文字に変換するだけです。
ここでは bash を使用しないでください。進むべき道は、ここにリストする時間よりも多くの理由で C++ で Boost を使用することですが、最終的には、遭遇する他のほとんどのソリューションと同じくらい高速になります。とにかく大きな違いを生む。
また、あなたがいつも遭遇するくだらない小さなハードコードされた日付変換ルーチンよりもはるかに柔軟で保守しやすいでしょう.
次のコードは、あなたが望むことを行います。
#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"
refの書式文字列を[1]
変更するだけで別の出力書式に変更されますが、大文字にも変換したことを思い出してください。
この形式の日付は比較的まれであるため、直接組み込まれているものはありません。%
ここでの最も簡単な解決策は、 と/
演算子 (例: month is )を使用して日付を年月日に分割しvalue / 100 % 100
、 を使用して 3 つの値を通常どおりにフォーマットstd::ostream
し、テーブルで日付を検索することです。(すべての整数値が有効な日付を生成するわけではないため、これには明らかに何らかのエラー チェックが必要です。)
古い質問に対する新しい回答。この回答は、<chrono>
Ctm
や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++ 日付/時刻ライブラリを使用する利点の 1 つは、簡単に変更できることです。たとえば、タイムスタンプを日単位の精度ではなく、ミリ秒単位の精度で解析する必要がある場合はどうでしょうか。これを行う方法は次のとおりです。
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 で必要になる場合もあります。の後に 1 行追加するだけparse
です。
tp = date::locate_zone("Pacific/Chatham")->to_sys(tp);
そして今、出力は次のとおりです。
30NOV2011 19:48:57.275000
任意のタイムゾーンと 1 秒未満の精度を考慮することは、現在、他のすべての C++ ライブラリの機能を超えています。