chronoライブラリによるカレンダー計算
A
duration
type measures time between two points in time (time_point
s). Aduration
has 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 anyint
value, 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
unsigned
value, 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
unsigned
value, which will be subsequently truncated to fit intoday
's unspecified internal storage." ↩︎
C++ Advent Calendar 2021参加記事「🕒時刻計算と📅カレンダー計算は違うよ。全然違うよ。」