namespace std::chrono {
class year_month_day;
}
概要
year_month_day
は、年、月、日を表すカレンダー表現のためクラスである。
このクラスは、年、および月に関する演算に対応している。ただし、日に関する演算はできない。
このクラスは等値比較および大小比較ができ、EqualityComparableおよびLessThanComparableの要件を満たす。
このクラスは、トリビアルコピー可能で、かつスタンダードレイアウト型である。
メンバ関数
構築/コピー/破棄
名前 | 説明 | 対応バージョン |
---|---|---|
(constructor) |
コンストラクタ | C++20 |
year_month_day& operator=(const year_month_day&) = default; year_month_day& operator=(year_month_day&&) = default; |
代入演算子 | C++20 |
算術演算
名前 | 説明 | 対応バージョン |
---|---|---|
operator+= |
加算の複合代入 | C++20 |
operator-= |
減算の複合代入 | C++20 |
観測
名前 | 説明 | 対応バージョン |
---|---|---|
year |
年要素を取得する | C++20 |
month |
月要素を取得する | C++20 |
day |
日要素を取得する | C++20 |
変換
名前 | 説明 | 対応バージョン |
---|---|---|
operator sys_days |
システム時間の日付への型変換演算子 | C++20 |
operator local_days |
ローカル時間の日付への型変換演算子 | C++20 |
検証
名前 | 説明 | 対応バージョン |
---|---|---|
ok |
値が範囲に収まっているか判定する | C++20 |
非メンバ関数
算術演算
名前 | 説明 | 対応バージョン |
---|---|---|
operator+ |
加算 | C++20 |
operator- |
減算 | C++20 |
比較演算
名前 | 説明 | 対応バージョン |
---|---|---|
operator== |
等値比較を行う | C++20 |
bool operator!=(const year_month_day&, const year_month_day&) noexcept; |
非等値比較を行う (== により使用可能) |
C++20 |
operator<=> |
三方比較を行う | C++20 |
bool operator<(const year_month_day&, const year_month_day&) noexcept; |
左辺が右辺より小さいかを判定する (<=> により使用可能) |
C++20 |
bool operator<=(const year_month_day&, const year_month_day&) noexcept; |
左辺が右辺以下を判定する (<=> により使用可能) |
C++20 |
bool operator>(const year_month_day&, const year_month_day&) noexcept; |
左辺が右辺より大きいかを判定する (<=> により使用可能) |
C++20 |
bool operator>=(const year_month_day&, const year_month_day&) noexcept; |
左辺が右辺以上を判定する (<=> により使用可能) |
C++20 |
入出力
名前 | 説明 | 対応バージョン |
---|---|---|
operator<< |
出力ストリームに出力する | C++20 |
from_stream |
フォーマット指定して入力ストリームから入力する | C++20 |
文字列フォーマットサポート
名前 | 説明 | 対応バージョン |
---|---|---|
formatter |
std::formatter クラスの特殊化 |
C++20 |
ハッシュサポート
名前 | 説明 | 対応バージョン |
---|---|---|
template <class T> struct hash; |
hash クラスの先行宣言 |
C++26 |
template<> struct hash<chrono::year_month_day>; |
hash クラスのyear_month_day に対する特殊化 |
C++26 |
例
基本的な使い方 (C++20)
#include <iostream>
#include <chrono>
namespace chrono = std::chrono;
using namespace std::chrono_literals;
int main()
{
// すべて2020年3月1日を表す
chrono::year_month_day date1 = 2020y/3/1;
chrono::year_month_day date2 = 2020y/chrono::March/1;
chrono::year_month_day date3 = 2020y/chrono::March/1d;
chrono::year_month_day date4 = 1d/chrono::March/2020;
chrono::year_month_day date5 = 1d/3/2020;
chrono::year_month_day date6 = chrono::March/1/2020;
chrono::year_month_day date7 = 3/1d/2020;
// 各カレンダー要素のコンストラクタはexplicitなので、
// 指定順は年、月、日で決まっているが、int値は指定できない
chrono::year_month_day date8{2020y, chrono::March, 1d};
chrono::year_month_day date9{chrono::year{2020}, chrono::month{3}, chrono::day{1}};
std::cout << date9 << std::endl;
// 年、月、月の最終日の組み合わせから、年、月、日に変換。
// 以下はすべて2020年2月29日を表す
chrono::year_month_day date10 = 2020y/3/chrono::last;
chrono::year_month_day date11 = 3/chrono::last/2020;
chrono::year_month_day date12 = chrono::last/3/2020;
std::cout << date12 << std::endl;
// 日単位のシステム時間に変換
chrono::sys_days sd{date9};
std::cout << sd << std::endl;
std::cout << sd.time_since_epoch().count() << std::endl; // 1970年1月1日からの経過日
std::cout <<
chrono::time_point_cast<chrono::seconds>(sd).time_since_epoch().count()
<< std::endl; // 1970年1月1日からの経過秒
// 日単位のシステム時間に時・分を加算して、分まで扱えるシステム時間に変換。
chrono::sys_time sm = chrono::sys_days{2020y/3/1} + 15h + 30min;
std::cout << sm << std::endl;
}
43
chrono::year_month_day date9{chrono::year{2020}, chrono::month{3}, chrono::day{1}};
#include <iostream>
#include <chrono>
namespace chrono = std::chrono;
using namespace std::chrono_literals;
int main()
{
// すべて2020年3月1日を表す
chrono::year_month_day date1 = 2020y/3/1;
chrono::year_month_day date2 = 2020y/chrono::March/1;
chrono::year_month_day date3 = 2020y/chrono::March/1d;
chrono::year_month_day date4 = 1d/chrono::March/2020;
chrono::year_month_day date5 = 1d/3/2020;
chrono::year_month_day date6 = chrono::March/1/2020;
chrono::year_month_day date7 = 3/1d/2020;
// 各カレンダー要素のコンストラクタはexplicitなので、
出力例
2020-03-01
2020-02-29
2020-03-01
18322
1583020800
2020-03-01 15:30:00
前月の末日を求める (C++20)
#include <cassert>
#include <chrono>
namespace chrono = std::chrono;
using namespace std::chrono_literals;
int main()
{
chrono::year_month_day base_date = 2020y/3/1;
// year_month_dayオブジェクトに対して直接1日減算はできないので、
// 前月の末日を表すyear_month_day_lastオブジェクトを作ってから、
// year_month_dayオブジェクトに変換する
chrono::year_month_day date{base_date.year()/(base_date.month() - chrono::months{1})/chrono::last};
assert(date == 2020y/2/29);
}
18
#include <cassert>
#include <chrono>
namespace chrono = std::chrono;
using namespace std::chrono_literals;
int main()
{
chrono::year_month_day base_date = 2020y/3/1;
// year_month_dayオブジェクトに対して直接1日減算はできないので、
// 前月の末日を表すyear_month_day_lastオブジェクトを作ってから、
// year_month_dayオブジェクトに変換する
chrono::year_month_day date{base_date.year()/(base_date.month() - chrono::months{1})/chrono::last};
assert(date == 2020y/2/29);
}
出力
UNIX時間からyear_month_dayオブジェクトに変換する (C++20)
#include <iostream>
#include <chrono>
namespace chrono = std::chrono;
chrono::year_month_day unix_time_to_ymd(std::time_t unixtime) {
// システム時間の時間点に変換
auto tp = chrono::system_clock::from_time_t(unixtime);
// 時間点を日単位に変換
chrono::sys_days sd = chrono::floor<chrono::days>(tp);
// 日付に変換
return chrono::year_month_day{sd};
}
int main()
{
// UNIX時間での現在日時を取得
std::time_t now = std::time(nullptr);
chrono::year_month_day date = unix_time_to_ymd(now);
std::cout << date << std::endl;
}
25
#include <iostream>
#include <chrono>
namespace chrono = std::chrono;
chrono::year_month_day unix_time_to_ymd(std::time_t unixtime) {
// システム時間の時間点に変換
auto tp = chrono::system_clock::from_time_t(unixtime);
// 時間点を日単位に変換
chrono::sys_days sd = chrono::floor<chrono::days>(tp);
// 日付に変換
return chrono::year_month_day{sd};
}
int main()
{
出力例
2019-12-20
生年月日から年齢を求める (C++20)
#include <iostream>
#include <chrono>
#include <stdexcept>
int calc_age(const std::chrono::year_month_day& date) {
if (!date.ok()) {
throw std::invalid_argument("invalid date");
}
namespace chrono = std::chrono;
chrono::year_month_day now {chrono::floor<chrono::days>(chrono::system_clock::now())};
int age = (now.year() - date.year()).count();
if (now.month() < date.month()) {
return age - 1;
}
else if (now.month() == date.month()) {
if (now.day() < date.day()) {
return age - 1;
}
}
return age;
}
int calc_age(int year, int month, int day) {
namespace chrono = std::chrono;
return calc_age(chrono::year_month_day{
chrono::year{year},
chrono::month{static_cast<unsigned int>(month)},
chrono::day{static_cast<unsigned int>(day)}});
}
int main()
{
using namespace std::chrono_literals;
std::cout << calc_age(1985y/3/1) << std::endl;
std::cout << calc_age(1954y/10/30) << std::endl; // 1970年未満も扱える
std::cout << calc_age(2000, 2, 29) << std::endl; // うるう年
}
xxxxxxxxxx
#include <iostream>
#include <chrono>
#include <stdexcept>
int calc_age(const std::chrono::year_month_day& date) {
if (!date.ok()) {
throw std::invalid_argument("invalid date");
}
namespace chrono = std::chrono;
chrono::year_month_day now {chrono::floor<chrono::days>(chrono::system_clock::now())};
int age = (now.year() - date.year()).count();
if (now.month() < date.month()) {
return age - 1;
}
else if (now.month() == date.month()) {
if (now.day() < date.day()) {
return age - 1;
出力例
34
65
19
2020年1月7日に実行した。
バージョン
言語
- C++20
処理系
- Clang: 8.0 (入出力ストリームなし) ✅
- GCC: 9.2 ❌
- Visual C++: 2019 Update 3 ❌
参照
- P2592R3 Hashing support for
std::chrono
value classes- C++26でハッシュサポートが追加された