iter_type
get(iter_type s,
iter_type end,
ios_base& f,
ios_base::iostate& err,
tm* t,
char format,
char modifier = 0) const; // (1) C++11
iter_type
get(iter_type s,
iter_type end,
ios_base& f,
ios_base::iostate& err,
tm* t,
const char_type* fmt,
const char_type* fmtend) const; // (2) C++11
概要
入力イテレータ範囲[s, end)から、書式を指定して日時を解析する。
- (1) : 単一の書式指定子
format(と修飾子modifier)に従って解析する - (2) : 範囲
[fmt, fmtend)を書式文字列として解析する
事前条件
- (2) :
[fmt, fmtend)が妥当な範囲であること
効果
- (2) :
err =std::ios_base::goodbitを評価したのち、各反復でsから0個以上の文字を読み取るループに入る。ループは以下のいずれかが最初に成立したときに終了するfmt == fmtendがtrueであるerr ==std::ios_base::goodbitがfalseであるs == endがtrueである。この場合、err =std::ios_base::eofbit|std::ios_base::failbitを評価するfmtの次の要素が'%'であり、省略可能な修飾子文字と変換指定子文字formatが続いて、POSIX関数strptimeにとって妥当な変換指定を形成する場合。範囲[fmt, fmtend)の要素数が、変換指定が完全かつ妥当であるかを曖昧さなく判定するのに不足している場合はerr =std::ios_base::failbitを評価する。そうでない場合はs =do_get(s, end, f, err, t, format, modifier)を評価する(修飾子がない場合、modifierの値は'\0'である)。評価後にerr ==std::ios_base::goodbitであれば、fmtを変換指定の終端の直後まで進めてループを継続するisspace(*fmt, f.getloc())がtrueである場合。この場合、まずfmt == fmtend || !isspace(*fmt, f.getloc())がtrueになるまでfmtを進め、次にs == end || !isspace(*s, f.getloc())がtrueになるまでsを進めて、ループを再開するsから読み取った次の文字が、fmtが指す要素と大文字小文字を区別しない比較で一致する場合。この場合++fmt, ++sを評価してループを継続する。一致しない場合はerr =std::ios_base::failbitを評価する
戻り値
- (1) :
do_get(s, end, f, err, t, format, modifier) - (2) :
s
備考
- (2) : 妥当な空白文字の判定には、
fのロケールに設定されたctype<charT>ファセットが使用される。大文字小文字を区別しない比較をどのような手段で行うか、およびその際に複数文字の並びを考慮するかは未規定である
例
基本的な使い方
#include <iostream>
#include <sstream>
#include <locale>
#include <iterator>
#include <ctime>
int main()
{
std::istringstream iss{"2026-08-25"};
const auto& facet = std::use_facet<std::time_get<char>>(iss.getloc());
std::tm t{};
std::ios_base::iostate err = std::ios_base::goodbit;
// (2) 書式文字列を指定する
const char fmt[] = "%Y-%m-%d";
facet.get(std::istreambuf_iterator<char>{iss},
std::istreambuf_iterator<char>{},
iss, err, &t, fmt, fmt + 8);
std::cout << t.tm_year << ' ' << t.tm_mon << ' ' << t.tm_mday << std::endl;
}
出力
126 7 25
ロケールによる違い
%x(日付)のようにCロケールに依存すると規定されている書式指定子は、ストリームのロケールによって解析される書式が変わる。
#include <iostream>
#include <sstream>
#include <locale>
#include <iterator>
#include <ctime>
#include <stdexcept>
const char* to_string(std::time_base::dateorder order)
{
switch (order) {
case std::time_base::no_order: return "no_order";
case std::time_base::dmy: return "dmy";
case std::time_base::mdy: return "mdy";
case std::time_base::ymd: return "ymd";
case std::time_base::ydm: return "ydm";
}
return "";
}
int main()
{
const char* names[] = {"en_US.UTF-8", "ja_JP.UTF-8", "de_DE.UTF-8"};
// 各ロケールの%xの書式で書かれた、同じ日付
const char* texts[] = {"08/25/2026", "2026/08/25", "25.08.2026"};
for (int i = 0; i < 3; ++i) {
try {
std::istringstream iss{texts[i]};
iss.imbue(std::locale{names[i]});
const auto& facet = std::use_facet<std::time_get<char>>(iss.getloc());
std::tm t{};
std::ios_base::iostate err = std::ios_base::goodbit;
const char fmt[] = "%x";
facet.get(std::istreambuf_iterator<char>{iss},
std::istreambuf_iterator<char>{},
iss, err, &t, fmt, fmt + 2);
std::cout << names[i] << std::endl;
std::cout << " date_order : " << to_string(facet.date_order()) << std::endl;
std::cout << " " << texts[i] << " -> "
<< (t.tm_year + 1900) << '/' << (t.tm_mon + 1) << '/' << t.tm_mday
<< std::endl;
}
catch (const std::runtime_error&) {
// 指定した名前のロケールが利用できない場合
std::cout << names[i] << " : not available" << std::endl;
}
}
}
出力例
en_US.UTF-8
date_order : mdy
08/25/2026 -> 2026/8/25
ja_JP.UTF-8
date_order : ymd
2026/08/25 -> 2026/8/25
de_DE.UTF-8
date_order : dmy
25.08.2026 -> 2026/8/25
- 書かれ方が異なる3つの日付文字列が、いずれも同じ日付として解析される
- 各ロケールにおける日付の要素の並び順は
date_order()で取得できる - 妥当なロケール名は処理系定義である。指定した名前のロケールが利用できない場合、
std::localeのコンストラクタはstd::runtime_errorを送出し、上記の例ではnot availableが出力される
バージョン
言語
- C++11