kkAyatakaのメモ帳。

誰かの役に立つかもしれない備忘録。

Boost.DateTimeのフォーマット

gregorian::dateやposix_time::ptimeはISO形式での出力になる。日付を「/」区切りや、ファイルパス/名前などに利用したりと、都合よく整形したい場合はそれぞれのfacetを利用する。

date_facet, time_facet

変換は、gregorian::date_facet、posix_time::time_facetを準備し、stringstream経由で行う。以下はposix_timeの例。

#include <boost/date_time.hpp>

// note: facetの寿命管理はlocaleが受け持つのでdelete不要
posix_time::time_facet *f = new posix_time::time_facet("%Y/%m/%d");

std::ostringstream oss;
oss.imbue(std::locale(oss.getloc(), f));

oss << now;
oss.str(); // "2013/05/05"

注意するのはfacetの寿命管理で、localeがdeleteする責任を引き継ぐらしい。はじめ、プログラムが落ちる理由が分からず結構混乱した...

まあ、サンプルどおりに打ったら動くわけで。localeについて調べたら、仕様書にそれらしい記載があって、こことかここにも記載が。あとVC++ソースコード。facet使ったの初めてだったので、はまりました。

フォーマットのフラグはリファレンスを適宜参照。

date_input_facet, time_input_facet

入力側。以下は、gregorian::date_input_facetの例。

#include <boost/date_time.hpp>

gregorian::date_input_facet *df =
  new gregorian::date_input_facet("%Y年%m月%d日");

std::istringstream iss("2013年05月05日");
iss.imbue(std::locale(iss.getloc(), df));

iss >> date;

サンプル

現在時刻から日付を「/」区切りで出力。また、日本語表記から入力。

#include <iostream>
#include <sstream>

#include <boost/date_time.hpp>

int main(const int argc, const char * const argv[]) {
  using namespace boost;

  // posix_time::time_facet
  posix_time::time_facet *f = new posix_time::time_facet("%Y/%m/%d");

  std::ostringstream oss;
  oss.imbue(std::locale(oss.getloc(), f));

  posix_time::ptime now = posix_time::second_clock::local_time();
  oss << now;

  std::cout << oss.str() << std::endl;

  // gregorian::date_input_facet
  gregorian::date_input_facet *df = new gregorian::date_input_facet("%Y年%m月%d日");

  std::istringstream iss("2013年05月05日");
  iss.imbue(std::locale(iss.getloc(), df));

  gregorian::date date;
  iss >> date;

  std::cout << date << std::endl;

  return 0;
}