Boost を用いて ISO 8601(正確には RFC 3339)フォーマット日時を出力するサンプルです。
#include <iostream>
#include <boost/date_time/c_local_time_adjustor.hpp>
#include <boost/date_time/local_time/local_time.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
std::string current_local_time() {
const auto current_time = boost::posix_time::microsec_clock::local_time();
const auto utc_timestamp = boost::posix_time::second_clock::universal_time();
const auto local_timestamp = boost::date_time::c_local_adjustor<boost::posix_time::ptime>::utc_to_local(utc_timestamp);
const auto td = local_timestamp - utc_timestamp;
std::ostringstream oss;
oss << boost::posix_time::to_iso_extended_string(current_time);
oss << (td.is_negative() ? '-' : '+');
oss << std::setw(2) << std::setfill('0');
oss << boost::date_time::absolute_value(td.hours());
oss << ':';
oss << std::setw(2) << std::setfill('0');
oss << boost::date_time::absolute_value(td.minutes());
return oss.str();
}
int main() {
std::cout << current_local_time() << std::endl;
return 0;
}
以下のようにビルドして実行します。Boost のインクルードパスは環境に合わせて適宜変更してください。
$ g++ main.cpp -std=c++11 -I/usr/local/Cellar/boost/1.66.0/include -lboost_date_time
$ ./a.out
2018-02-24T00:09:55.980492+09:00
蛇足
ISO 8601 と RFC 3339 は、それぞれ詳細を確認して貰いたいのですが、簡単に特徴と違いをまとめると:
- ISO 8601 は
20180102T212223Z
または20180102T212223+0900
が基本形式で、2018-01-02T21:22:23Z
または2018-01-02T21:22:23+0900
が拡張形式-
2018-01-02T21:22Z
や2018-01-02T21Z
のような精度も可 - 末尾には小数点を指定可能で
2018-01-02T21:22:23,5Z
、2018-01-02T21:22,5Z
、2018-01-02T21,5Z
などの指定が可能(それぞれ21:22:23.5
、21:22:30
、21:30:00
を意味する) - 小数点はカンマが推奨されるが、ピリオドでも可
- T または Z は小文字も可
-
- RFC 3339 は秒未満の精度を持つ
2018-01-02T21:22:23.123456Z
または2018-01-02T21:22:23.123456+09:00
- 秒未満の桁数は任意
という感じです。
ここでは詳細を省略していますが ISO 8601 はもっともっとあいまいなフォーマットで、例えば YYYY-DDD
という表記で月を省略したり YYYY-Www-D
で第何週の何曜日かを表したりもできます。ISO 8601 といえば上述の箇条書きのフォーマットが一般的に認知されており、こうした特殊なフォーマットはあまり使われないと思いますが、ISO 8601 の拡張かつサブセットである RFC 3339 がフォーマットとしてはカチッとしていて扱いやすいです。
今回の記事は ISO 8601 フォーマットを出力するなら strftime で比較的簡単に出力できるのですが、RFC 3339 を出力するベストプラクティスがネット上で見つからなかったので1作成しました。
-
実際には C++ & ISO8601 : 時刻文字列 "2016-01-25T15:30:15.123+09:00" を出力する例 - Qiita がすぐに見つかったのですが、実装が大きくて複雑なので採用できませんでした(すみません) ↩