9#include <botan/internal/calendar.h>
11#include <botan/assert.h>
12#include <botan/exceptn.h>
29int64_t days_since_epoch(uint32_t year, uint32_t month, uint32_t day) {
35 const uint32_t era = year / 400;
36 const uint32_t yoe = year - era * 400;
37 const uint32_t doy = (153 * (month + (month > 2 ? -3 : 9)) + 2) / 5 + day - 1;
38 const uint32_t doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
39 return static_cast<int64_t
>(era) * 146097 +
static_cast<int64_t
>(doe) - 719468;
50std::array<uint32_t, 6> civil_from_time_point(
const std::chrono::system_clock::time_point& tp) {
51 const int64_t t =
static_cast<int64_t
>(std::chrono::system_clock::to_time_t(tp));
55 int64_t days = t / 86400;
56 int64_t tod = t % 86400;
62 const int64_t z = days + 719468;
63 const int64_t era = (z >= 0 ? z : z - 146096) / 146097;
64 const int64_t doe = z - era * 146097;
65 const int64_t yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365;
66 const int64_t y = yoe + era * 400;
67 const int64_t doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
68 const int64_t mp = (5 * doy + 2) / 153;
69 const int64_t day = doy - (153 * mp + 2) / 5 + 1;
70 const int64_t month = mp < 10 ? mp + 3 : mp - 9;
71 const int64_t year = y + (month <= 2 ? 1 : 0);
73 return {
static_cast<uint32_t
>(year),
74 static_cast<uint32_t
>(month),
75 static_cast<uint32_t
>(day),
76 static_cast<uint32_t
>(tod / 3600),
77 static_cast<uint32_t
>((tod % 3600) / 60),
78 static_cast<uint32_t
>(tod % 60)};
84 m_year(static_cast<uint16_t>(y)),
85 m_month(static_cast<uint8_t>(mon)),
86 m_day(static_cast<uint8_t>(d)),
87 m_hour(static_cast<uint8_t>(h)),
88 m_minutes(static_cast<uint8_t>(min)),
89 m_seconds(static_cast<uint8_t>(sec)) {
110 constexpr int64_t max_representable_seconds =
static_cast<int64_t
>(
111 std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::duration::max()).count());
112 constexpr int64_t min_representable_seconds =
static_cast<int64_t
>(
113 std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::duration::min()).count());
115 if(seconds_64 > max_representable_seconds || seconds_64 < min_representable_seconds) {
116 throw Invalid_Argument(
"calendar_point::to_std_timepoint time is outside the representable range");
119 const time_t seconds_time_t =
static_cast<time_t
>(seconds_64);
121 if(seconds_64 - seconds_time_t != 0) {
122 throw Invalid_Argument(
"calendar_point::to_std_timepoint time is outside the representable range");
125 return std::chrono::system_clock::from_time_t(seconds_time_t);
129 const auto [
year,
month,
day,
hour, minute, second] = civil_from_time_point(time_point);
133 m_year =
static_cast<uint16_t
>(
year);
134 m_month =
static_cast<uint8_t
>(
month);
135 m_day =
static_cast<uint8_t
>(
day);
136 m_hour =
static_cast<uint8_t
>(
hour);
137 m_minutes =
static_cast<uint8_t
>(minute);
138 m_seconds =
static_cast<uint8_t
>(second);
#define BOTAN_ARG_CHECK(expr, msg)
int64_t seconds_since_epoch() const
std::chrono::system_clock::time_point to_std_timepoint() const
calendar_point(uint32_t y, uint32_t mon, uint32_t d, uint32_t h, uint32_t min, uint32_t sec)