chronoライブラリによるカレンダー計算
A
durationtype measures time between two points in time (time_points). Adurationhas a representation which holds a count of ticks and a tick period. The tick period is the amount of time which occurs from one tick to the next, in units of seconds. It is expressed as a rational constant using the templateratio.
template<class Duration>
using sys_time = time_point<system_clock, Duration>;
using sys_days = sys_time<days>;
using hours = duration</*...*/, ratio<3600>>;
using days = duration</*...*/, ratio_multiply<ratio<24>, hours::period>>;
using years = duration</*...*/, ratio_multiply<ratio<146097, 400>, days::period>>;
constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept;
// Returns: (ymd.year() + dy) / ymd.month() / ymd.day().
template<class Rep1, class Period1, class Rep2, class Period2>
struct common_type<chrono::duration<Rep1, Period1>, chrono::duration<Rep2, Period2>> {
using type = chrono::duration<common_type_t<Rep1, Rep2>, /*see below*/>;
};
// The period of the duration indicated by this specialization of common_type is
// the greatest common divisor of Period1 and Period2. [Note: This can be computed
// by forming a ratio of the greatest common divisor of Period1::num and Period2::num
// and the least common multiple of Period1::den and Period2::den. -- end note]
template<class Clock, class Duration1, class Rep2, class Period2>
constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
// Returns: CT(lhs.time_since_epoch() + rhs), where CT is the type of the return value.
-
days{1}= 24[時間] × 3600[秒] = 86400[秒] -
years{1}= 146097/400 [日] × 86400[秒] = 31556952[秒]- 365 × 303 + 366 × 97 = 146097[日];400年間周期で閏年は97回
-
years{1}= 31556952[秒] = 146097 × 216[秒]-
common_type_t<days, years>=duration</*...*/, ratio<216, 1>>
-
assert(sys_days{2020y/1/1 + years{1}} == sys_days{2021y/1/1}); // OK
assert(sys_days{2020y/1/1 + months{1}} == sys_days{2020y/2/1}); // OK
assert(sys_days{2020y/1/1 + days{100}} == sys_days{2020y/4/10}); // NG コンパイルエラー
// ^^^^^^^^^ ^^^^^^^^^
// year_month_day + days
式2020y/1/1の型year_month_dayでは、年yearsまたは月monthsに対する加減算をサポートする。日daysとの加減算オーバーロードは提供されない。
namespace std::chrono {
// [time.cal.ymd]
constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept;
constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept;
constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept;
constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept;
constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept;
constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept;
}
year_month_dayクラスはデータメンバとしてyear, month, dayクラスの値をもち;
-
yearクラスは年をshort型で保持する。値域[-32767,32767][1] -
monthクラスは月をunsigned char型で保持する。値域[0,255][2] -
dayクラスは日をunsigned char型で保持する。値域[0,255][3]
-
C++20 [time.cal.year.overview]/p1: "It can represent values in the range [
min(),max()]. It can be constructed with anyintvalue, which will be subsequently truncated to fit intoyear's unspecified internal storage." ↩︎ -
C++20 [time.cal.month.overview]/1: "It can be constructed with any
unsignedvalue, which will be subsequently truncated to fit intomonth's unspecified internal storage." ↩︎ -
C++20 [time.cal.day.overview]/1: "It can be constructed with any
unsignedvalue, which will be subsequently truncated to fit intoday's unspecified internal storage." ↩︎
C++ Advent Calendar 2021参加記事「🕒時刻計算と📅カレンダー計算は違うよ。全然違うよ。」