namespace std::chrono {
template <class Duration>
using file_time = time_point<file_clock, Duration>; // (1) C++20
template <class charT, class traits, class Duration>
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os,
const file_time<Duration>& tp); // (2) 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,
file_time<Duration>& tp,
std::basic_string<charT, traits, Alloc>* abbrev = nullptr,
minutes* offset = nullptr); // (3) C++20
}
namespace std {
template <class Duration, class charT>
struct formatter<chrono::file_time<Duration>, charT>; // (4) C++20
}
概要
ファイル時間の一点を指すtime_pointに対する別名。
この時間点はUTCタイムゾーンの時間を指す。
- (1) :
file_clockのtime_pointに対する別名。時間間隔を表す型はパラメータ化されている - (2) : 時間点に含まれる日付と時間を出力ストリームに出力する
- (3) : フォーマット指定して入力ストリームから日付・時間を時間点オブジェクトに入力する
- (4) :
file_time型に対するstd::formatterクラステンプレートの特殊化
効果
便宜上のリテラルキャストSTATICALLY-WIDENを導入する。STATICALLY-WIDEN<charT>("...")は、charTがcharである場合は"..."、charTがwchar_tである場合はL"..."を意味する。
-
(2) : 以下と等価:
return os << format(os.getloc(), STATICALLY-WIDEN<charT>("{:L%F %T}"), tp); -
(3) :
- パラメータ
fmtで指定されたフォーマットフラグを使用して、入力を解析し、tpに代入する - 有効な日付・時間の解析に失敗した場合、
is.setstate(ios_base::failbit)が呼び出され、パラメータtpは変更されない - タイムゾーンフォーマット
"%Z"が指定され、解析が成功した場合、パラメータabbrevが非ヌルである場合に*abbrevにタイムゾーン名が代入される - タイムゾーンとしてUTC時間からのオフセット時間 (日本なら
"+0900") を意味するフォーマット"%z"が指定され、解析が成功した場合、パラメータoffsetが非ヌルである場合に*offsetにその値が代入される - さらに、
tpに日付・時間が代入される前に、解析されたオフセットがタイムスタンプから引かれる isを返す
- パラメータ
備考
- (1) : このバージョンは、関数テンプレートで任意の時間間隔単位の
time_pointを受け取るために使用できる。file_clock::time_pointがもつ時間間隔の単位は未規定 (実装定義) であるため、特定の単位に決めることができないため、時間間隔の型のみをパラメータ化して関数テンプレートで受け取ると便利である - (4) :
%Z(タイムゾーンの略称) が指定された場合、STATICALLY-WIDEN<charT>("UTC")で置き換えられる%zもしくはその改良コマンドが指定された場合、0minが使用される- この日付と時間のフォーマットは、
file_time<Duration>型変数tをclock_cast<system_clock>(t)で変換したsys_time、もしくはclock_cast<utc_clock>(t)で変換したutc_timeをフォーマットした場合と等価である
例
基本的な使い方
#include <iostream>
#include <fstream>
#include <chrono>
#include <filesystem>
#include <fstream>
namespace chrono = std::chrono;
namespace fs = std::filesystem;
int main()
{
std::ofstream{"regular.txt"};
// ファイルの最終更新日時を取得して出力
fs::file_time_type tp = fs::last_write_time("regular.txt");
std::cout << tp << std::endl;
}
出力例
2019-10-24 11:15:10
入力の例
#include <iostream>
#include <sstream>
#include <chrono>
#include <filesystem>
namespace chrono = std::chrono;
namespace fs = std::filesystem;
int main()
{
// タイムゾーンとオフセットを含まない入力
{
std::stringstream ss;
ss << "2019-10-24 20:15:10";
fs::file_time_type 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 UTC +0900";
fs::file_time_type tp;
std::string abbrev;
chrono::minutes offset{0};
chrono::from_stream(ss, "%Y-%m-%d %H:%M:%S %Z %z", tp, &abbrev, &offset);
std::cout << tp << std::endl;
std::cout << abbrev << std::endl;
std::cout << offset.count() << std::endl;
}
}
出力例
2019-10-24 11:15:10
2019-10-24 11:15:10
UTC
540
文字列フォーマットの例
#include <iostream>
#include <chrono>
#include <format>
#include <filesystem>
#include <fstream>
namespace chrono = std::chrono;
namespace fs = std::filesystem;
int main()
{
std::ofstream{"regular.txt"};
// ファイルの最終更新日時を取得して出力
fs::file_time_type tp = fs::last_write_time("regular.txt");
// デフォルトフォーマット
std::cout << std::format("1 : {}", tp) << std::endl;
// 「年月日 時分秒」のフォーマット
std::cout << std::format("2 : {:%Y年%m月%d日 %H時%M分%S秒}", tp) << std::endl;
// 日付を / (スラッシュ) 区切り、時間を : (コロン) 区切り
std::cout << std::format("3 : {0:%Y/%m/%d %H:%M:%S}", tp) << std::endl;
// 日付だけ出力
std::cout << std::format("4 : {:%Y年%m月%d日}", tp) << std::endl;
std::cout << std::format("5 : {:%F}", tp) << std::endl;
// 時間だけ出力
std::cout << std::format("6 : {:%H時%M分%S秒}", tp) << std::endl;
std::cout << std::format("7 : {:%T}", tp) << std::endl;
}
出力例
1 : 2019-12-20 10:05:00
2 : 2019年12月20日 10時05分05秒
3 : 2019/12/20 10:05:05
4 : 2019年12月20日
5 : 2019-12-20
6 : 10時05分05秒
7 : 10:05:05
バージョン
言語
- C++20
処理系
- Clang: 9.0 ❌
- GCC: 9.2 ❌, 15.1 ✅
- Visual C++: 2019 Update 3 ❌
関連項目
- chronoの
std::format()(出力フォーマットの詳細) - chronoの
parse()(入力フォーマットの詳細)
参照
- P2372R1 Fixing locale handling in chrono formatters
- この提案文書はC++20の策定後に採択されたが、実装が追いついていない時期の採択だったために、C++20の仕様として扱われる