Open3

# chronoライブラリによるカレンダー計算

C++20 (N4861) [time]

A `duration` type measures time between two points in time (`time_­point`s). A `duration` 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 template `ratio`.

``````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]

1. C++20 [time.cal.year.overview]/p1: "It can represent values in the range [`min()`, `max()`]. It can be constructed with any `int` value, which will be subsequently truncated to fit into `year`'s unspecified internal storage." ↩︎

2. C++20 [time.cal.month.overview]/1: "It can be constructed with any `unsigned` value, which will be subsequently truncated to fit into `month`'s unspecified internal storage." ↩︎

3. C++20 [time.cal.day.overview]/1: "It can be constructed with any `unsigned` value, which will be subsequently truncated to fit into `day`'s unspecified internal storage." ↩︎

ログインするとコメントできます