- chrono[meta header]
- std::chrono[meta namespace]
- type-alias[meta id-type]
- cpp20[meta cpp]
namespace std::chrono {
template <class Duration>
using tai_time = time_point<tai_clock, Duration>; // (1) C++20
using tai_seconds = tai_time<seconds>; // (2) C++20
template <class charT, class traits, class Duration>
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os,
const tai_time<Duration>& tp); // (3) C++20
template <class charT, class traits, class Duration, class Alloc = std::allocator<charT>>
std::basic_istream<charT, traits>&
from_stream(std::basic_istream<charT, traits>& is,
const charT* fmt,
tai_time<Duration>& tp,
std::basic_string<charT, traits, Alloc>* abbrev = nullptr,
minutes* offset = nullptr); // (4) C++20
}
namespace std {
template <class Duration, class charT>
struct formatter<chrono::tai_time<Duration>, charT>; // (5) C++20
}
- time_point[link time_point.md]
- tai_clock[link tai_clock.md]
TAI時間の一点を指すtime_point
に対する別名。
- (1) :
tai_clock
のtime_point
に対する別名。時間間隔を表す型はパラメータ化されている - (2) : 秒単位でTAI時間の一点を指す
time_point
に対する別名 - (3) : 時間点に含まれる日付と時間を出力ストリームに出力する
- (4) : フォーマット指定して入力ストリームから日付・時間を時間点オブジェクトに入力する
- (5) :
tai_time
型に対するstd::formatter
クラステンプレートの特殊化
便宜上のリテラルキャストSTATICALLY-WIDEN
を導入する。STATICALLY-WIDEN<charT>("...")
は、charT
がchar
である場合は"..."
、charT
がwchar_t
である場合はL"..."
を意味する。
-
(3) : 以下と等価:
return os << format(os.getloc(), STATICALLY-WIDEN<charT>("{:L%F %T}"), tp);
- format[link format.md]
- os.getloc()[link /reference/ios/ios_base/getloc.md]
-
(4) :
- パラメータ
fmt
で指定されたフォーマットフラグを使用して、入力を解析し、tp
に代入する - 有効な日付・時間の解析に失敗した場合、
is.
setstate
(
ios_base::failbit
)
が呼び出され、パラメータtp
は変更されない - タイムゾーンフォーマット
"%Z"
が指定され、解析が成功した場合、パラメータabbrev
が非ヌルである場合に*abbrev
にタイムゾーン名が代入される - オフセット時間を意味するフォーマット
"%z"
が指定され、解析が成功した場合、パラメータoffset
が非ヌルである場合に*offset
にその値が代入される - さらに、
tp
に日付・時間が代入される前に、解析されたオフセットがタイムスタンプから引かれる is
を返す
- パラメータ
- (1) : このバージョンは、関数テンプレートで任意の時間間隔単位の
time_point
を受け取るために使用できる。tai_clock::time_point
がもつ時間間隔の単位は未規定 (実装定義) であるため、特定の単位に決めることができないため、時間間隔の型のみをパラメータ化して関数テンプレートで受け取ると便利である - (5) :
%Z
(タイムゾーンの略称) が指定された場合、STATICALLY-WIDEN<charT>("TAI")
で置き換えられる%z
もしくはその改良コマンドが指定された場合、0
min
が使用される- この日付と時間のフォーマットは、
gps_time<Duration>
型変数tp
を以下のように変換したsys_time
をフォーマットした場合と等価:sys_time<Duration>{tp.time_since_epoch()} + (sys_days{1970y/January/1} - sys_days{1958y/January/1})
- sys_time[link sys_time.md]
- tp.time_since_epoch()[link time_point/time_since_epoch.md]
- sys_days[link sys_time.md]
- 1970y[link year/op_y.md]
- 1958y[link year/op_y.md]
- January[link month_constants.md]
#include <iostream>
#include <chrono>
namespace chrono = std::chrono;
int main()
{
// 未規定の時間間隔単位をもつ時間点
chrono::tai_clock::time_point tp = chrono::tai_clock::now();
// 秒単位の時間点 (日付と時間が出力される)
chrono::tai_seconds sec_p = chrono::time_point_cast<chrono::seconds>(tp);
std::cout << sec_p << std::endl;
}
- chrono::tai_seconds[color ff0000]
- chrono::tai_clock[link tai_clock.md]
- now()[link tai_clock/now.md]
- chrono::time_point_cast[link time_point_cast.md]
2019-10-24 11:15:37 TAI
#include <iostream>
#include <sstream>
#include <chrono>
namespace chrono = std::chrono;
int main()
{
// タイムゾーンとオフセットを含まない入力
{
std::stringstream ss;
ss << "2019-10-24 20:15:37";
chrono::tai_seconds tp;
chrono::from_stream(ss, "%Y-%m-%d %H:%M:%S", tp);
if (ss) {
std::cout << tp << std::endl;
}
else {
std::cout << "解析失敗" << std::endl;
}
}
// タイムゾーンを含む入力
{
std::stringstream ss;
ss << "2019-10-24 20:15:10 TAI";
chrono::tai_seconds tp;
std::string abbrev;
chrono::from_stream(ss, "%Y-%m-%d %H:%M:%S %Z%z", tp, &abbrev);
std::cout << tp << std::endl;
std::cout << abbrev << std::endl;
}
}
- chrono::from_stream[color ff0000]
2019-10-24 11:15:37 TAI
2019-10-24 11:15:37 TAI
TAI
#include <iostream>
#include <chrono>
#include <format>
namespace chrono = std::chrono;
int main()
{
chrono::tai_clock::time_point now = chrono::tai_clock::now();
chrono::tai_seconds now_sec = chrono::floor<chrono::seconds>(tp);
// デフォルトフォーマット
std::cout << std::format("1 : {}", now_sec) << std::endl;
// 「年月日 時分秒」のフォーマット
std::cout << std::format("2 : {:%Y年%m月%d日 %H時%M分%S秒}", now_sec) << std::endl;
// 日付を / (スラッシュ) 区切り、時間を : (コロン) 区切り、タイムゾーンの略称付き
std::cout << std::format("3 : {0:%Y/%m/%d %H:%M:%S %Z}", now_sec) << std::endl;
// 日付だけ出力
std::cout << std::format("4 : %Y年%m月%d日", now_sec) << std::endl;
std::cout << std::format("5 : %F", now_sec) << std::endl;
// 時間だけ出力
std::cout << std::format("6 : %H時%M分%S秒", now_sec) << std::endl;
std::cout << std::format("7 : %T", now_sec) << std::endl;
}
- chrono::tai_clock[link tai_clock.md]
- now()[link tai_clock/now.md]
- chrono::floor[link time_point/floor.md]
- std::format[link format.md]
1 : 2019-12-20 10:05:05 TAI
2 : 2019年12月20日 10時05分05秒
3 : 2019/12/20 10:05:05 TAI
4 : 2019年12月20日
5 : 2019-12-20
6 : 10時05分05秒
7 : 10:05:05
- C++20
- Clang: 9.0 [mark noimpl]
- GCC: 9.2 [mark noimpl]
- Visual C++: 2019 Update 3 [mark noimpl]
- chronoの
std::format()
(出力フォーマットの詳細) - chronoの
parse()
(入力フォーマットの詳細)
- P2372R1 Fixing locale handling in chrono formatters
- この提案文書はC++20の策定後に採択されたが、実装が追いついていない時期の採択だったために、C++20の仕様として扱われる