Mar 18, 2023 at 12:57pm UTC
With C++20/23 std::chrono and a birthdate as either type sys_days or year_month_day, is there any 'easy' way to obtain their age as years, months and days. It's quite easy to get the age as a number of days (get the birthdate and today's date as sys_days and subtract) - but as years, months, days without doing calculations involving 365 and an array of days in months?
Mar 19, 2023 at 1:08pm UTC
We've come up with this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
struct Age {
unsigned years {};
unsigned months {};
unsigned days {};
bool good {};
};
...
// Obtain today's date
[[nodiscard]]
inline std::chrono::sys_days get_today() noexcept {
return std::chrono::floor<std::chrono::days>(std::chrono::system_clock::now());
}
// Obtain age as years/months/days
[[nodiscard]]
inline Age get_age(std::chrono::sys_days from, std::chrono::sys_days to = get_today()) noexcept {
// Check if been born!
if (from > to)
return {};
Age age { .days = unsigned ((to - from).count()), .good = true };
std::chrono::sys_days sd1 {};
for (std::chrono::year_month_day ymd { from }, ymd1 { ymd + std::chrono::months(1) }; (sd1 = std::chrono::sys_days(ymd1)) <= to; ++age.months, ymd = ymd1, ymd1 = ymd + std::chrono::months(1))
age.days -= (sd1 - std::chrono::sys_days(ymd)).count();
age.years = age.months / 12;
age.months %= 12;
return age;
}
We were hoping that with std::chrono to remove the loop, but this doesn't seem possible??
Last edited on Mar 20, 2023 at 10:21am UTC