最終更新日時:
が更新

履歴 編集

class template
<locale>

std::time_get

namespace std {
  template <class charT, class InputIterator = istreambuf_iterator<charT> >
  class time_get : public locale::facet, public time_base;
}

概要

time_getは、文字列を解析して日時の要素をstd::tmオブジェクトへ取り出すためのロケールファセットである。

getメンバ関数は、time_put::putの対応する書式指定子が生成する書式を解析する。解析対象の列が正しい書式に一致した場合、tm引数の対応するメンバにはその列を生成した値が設定される。そうでない場合は、エラーが報告されるか、未規定の値が代入される。

いずれかのget()メンバ関数の解析中に終端イテレータへ到達した場合、errstd::ios_base::eofbitが設定される。

メンバ関数

publicメンバ関数

名前 説明 対応バージョン
(constructor) コンストラクタ
date_order 日付の表記順を取得する
get_time 時間の解析
get_date 日付の解析
get_weekday 曜日の解析
get_monthname 月名の解析
get_year 年の解析
get 日時の解析 C++11

静的メンバ変数

名前 説明
static locale::id id; このファセットを識別するためのID

protectedメンバ関数

名前 説明 対応バージョン
(destructor) デストラクタ
do_date_order 日付の表記順を取得する (virtual)
do_get_time 時間の解析 (virtual)
do_get_date 日付の解析 (virtual)
do_get_weekday 曜日の解析 (virtual)
do_get_monthname 月名の解析 (virtual)
do_get_year 年の解析 (virtual)
do_get 日時の解析 (virtual) C++11

メンバ型

名前 説明
char_type 文字型 charT
iter_type 入力のイテレータ型 InputIterator

基本的な使い方

#include <iostream>
#include <sstream>
#include <locale>
#include <iterator>
#include <ctime>

int main()
{
  std::istringstream iss{"2026-08-25"};

  // ストリームのロケールからtime_getファセットを取得する
  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[] = "%Y-%m-%d";
  facet.get(std::istreambuf_iterator<char>{iss},
            std::istreambuf_iterator<char>{},
            iss, err, &t, fmt, fmt + 8);

  // tm_yearは1900年からの経過年数、tm_monは1月を0とする月番号
  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++98

関連項目