date icon indicating copy to clipboard operation
date copied to clipboard

Adding years with + and sys_days yields different result than += with year_month_day

Open QuantDevHacks opened this issue 2 years ago • 3 comments

I'm noticing a one-day discrepancy when adding years to a date, depending on whether a year_month_day is converted to sys_days with the + operator defined (incorrect result), or if += is applied to the original year_month_day object (correct).

A repro is as follows (Visual Studio compiler, ISO C++20 Standard):

using namespace std::chrono;

using std::cout;
using std::endl;

year_month_day ymd{ year{2002}, month{11}, day{14} };

auto add_years = sys_days(ymd) + years(20);   // Result is 2022-11-13 20:24:00 (incorrect)
cout << add_years  << endl;                   //  type is std::chrono::time_point<...>

ymd += years{ 20 };           // Result is 2022-11-14 (correct)
cout << ymd << endl;          // type is year_month_day

One more thing to note: the 20:24:00 time stamp in the 1st case is constant -- I tried this at different times but still got the same result.

QuantDevHacks avatar Aug 22 '22 05:08 QuantDevHacks

When you work with sys_days, you are using a time_point, which is a duration of time since a given epoch as defined by the given clock (not including leap seconds in the case of system_clock). On average there are 7304.85 days in 20 years, so you are getting the expected result there.

year_month_day is a calendar time instead of a time_point. Adding 20 years to 2002 produces 2022 and leaves the month and day alone, which is what you expected.

Erroneous1 avatar Aug 22 '22 15:08 Erroneous1

Here is an analogous description of adding months: https://stackoverflow.com/a/43018120/576911

It describes how there are both chronological and calendrical algorithms to do this arithmetic. Though it describes the situation with months, the situation with years is the same.

HowardHinnant avatar Aug 23 '22 12:08 HowardHinnant

Thanks very much to both of you for the follow-up. That makes it reasonably clear now.

QuantDevHacks avatar Aug 29 '22 17:08 QuantDevHacks