Search code examples
c++timec++20c++-chrono

How to get std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds> from variables of year,month,day,hour,minute and seconds?


I have declared a time_point variable and try to assign values from year month day etc. But it fails when I use sys_days. The code is something as follows.

int year=2023;
int month=1;
int day=1;
int hour=1;
int minute=1;
double second=0.000005;
std::chrono::time_point\<std::chrono::system_clock, std::chrono::seconds\> tp;
tp=sys_days{years{year}+months{month}+days{day}}+hour+minute+second;

The code encountered errors, but I don't know how to fix it. Thanks for helps.


Solution

  • double second = 0.000005;

    This line brings questions. Your title says that you want a time_point that holds integral seconds, but here you say you want a precision of microseconds, possibly held with double representation. These can't all be true.

    Assumption: You will be fine with a time_point holding an integral number of microseconds. To do this, change this line to:

    int us = 5;  // 5 microseconds
    

    Your use of some names that are in std::chrono, but without the std::chrono:: prefix, combined with variable names of the same spelling, leads to conflicts.

    Assumption: declare using namespace std::chrono and rename your int variables to avoid name conflicts:

    using namespace std::chrono;
    int y=2023;
    int m=1;
    int d=1;
    int h=1;
    int M=1;
    int us = 5;
    

    Your time_point type now must have a different type than that stated in your title:

    time_point<system_clock, microseconds> tp;
    

    This type has a type alias in C++20 that is slightly simpler:

    sys_time<microseconds> tp;
    

    The types years, months, and days are all plural, and all std::chrono::duration types. For specifying pieces of the civil calendar, you need the singular spelling of these names: year, month, and day. These are calendrical specifiers for the civil calendar.

    See What is the difference between chrono::month and chrono::months for more details on the difference between the singular and plural forms.

    The expression year(y)/month(m)/day(d) creates a year_month_day. One can convert this to sys_days which creates a day-precision time_point:

    sys_days{year{y}/month(m)/day(d)}
    

    To this you can add any duration type, but not ints:

    tp=sys_days{year{y}/month(m)/day(d)}+hours{h}+minutes{M}+microseconds{us};
    

    Unless you need to "pre declare" tp, the use of auto can simplify things greatly:

    auto tp = sys_days{year{y}/month(m)/day(d)}
              + hours{h} + minutes{M} + microseconds{us};