year_month_day vs sys_days

When dealing with dates - year, month, day (not times) - either year_month_day or sys_days can be used. Is there guidance as when one or the other should be used? Note that we frequently have to add/subtract a number of days or months from a date and it seems you can't add/subtract directly a number of days with year_month_day. Also to obtain the number of days between 2 dates (taking into account leap years). So on this basis sys_days would seem to be the better choice?? - but does using sys_days have any downsides compared to year_month_day?

We've trying to convert our date class to internally use C++20 std::chrono rather than our own internal representations/functions whilst keeping the same public interface.
Last edited on
You can't access the year, month and day of the month from sys_days directly. You would need to convert to year_month_day first.
Last edited on
> we frequently have to add/subtract a number of days or months from a date.
> Also to obtain the number of days between 2 dates (taking into account leap years).

An implicit conversion to and from std::chrono::sys_days allows std::chrono::days oriented arithmetic to be performed efficiently.
https://en.cppreference.com/w/cpp/chrono/year_month_day


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
#include <iostream>
#include <iomanip>
#include <chrono>
#include <sstream>
#include <string>

int main()
{
    using namespace std::chrono;

    // a work-around if std::cout << ymd or a std::formatter for year_month_day is not yet available
    const auto str = []( const year_month_day& ymd )
    {
        std::ostringstream stm ;
        stm << std::setfill('0') << std::setw(4) << int( ymd.year() ) << '/'
            << std::setw(2) << unsigned( ymd.month() ) << '/'
            << std::setw(2) << unsigned( ymd.day() ) ;
        return stm.str() ;
    };

    const year_month_day ymd = March/15/2023 ;
    const year_month_day ymd2 = March/15/2033 ;
    std::cout << str(ymd2) << " - " << str(ymd) << " == " << ( sys_days(ymd2) - sys_days(ymd) ).count() << " days\n"
              << str(ymd) << " + 730 days == " << str( year_month_day( sys_days(ymd) + days(730) ) ) << '\n' ;
}

http://coliru.stacked-crooked.com/a/4af2b3aef19e4655
Last edited on
Yes - but is it better to store as year_month_day and do the conversion each time it's needed in sys_days format or store as sys_days and do the conversion when access is needed to individual years, months etc? Most of our processing once a date has been obtained is day calculation which needs sys_days - with some month and weeks (just effectively days) calculation - that's why we've considering using sys_days. I just wondered if there was a reason why we should use year_month_day - but it seems to come down to minimising the number of conversions undertaken. Yes, we do have std::formatter for chrono - that works the same with both sys_days and year_month_day.
> it seems to come down to minimising the number of conversions undertaken

Yes, that -- or memory requirements?
Playing around with Compiler Explorer, it looks like sizeof(std::chrono::year_month_day) is 4 while sizeof(std::chrono::sys_days) is sometimes 4 and sometimes 8 so if you prioritize memory over everything else it looks like you should go for std::chrono::year_month_day.
Last edited on
With VS (64-bit compile) I get 4 for both sys_days and year_month_day. When do you get 8 for sys_days?
Ive wanted to just move to some sort of epoch/stardate/whatever you want to call it using 64 bit as yyyymmddhhmmss[. implied not real decimal]ssss or however many fractional seconds you can stuff into it for a long, long time now. handily, you only need {0,1,2} for the first y for the forseeable future, so it would be really optimistic to worry about that digit. This is just a ramble, but if it were me, I would do-over. Its probably suboptimal for some date math but its human readable is the tradeoff.
Last edited on
For this, I'm only interested in date and not time.
seeplus wrote:
When do you get 8 for sys_days?

libstdc++ (64-bit)
https://godbolt.org/z/qazrq6hev
Topic archived. No new replies allowed.