Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert ‘std::chrono::duration<int, std::ratio<2629746l, 1l> >’ to ‘int’ type?

I am using Howard Hinnant's date library, and trying to find the total number of months between two dates.

invalid static_cast from type ‘std::chrono::duration<int, std::ratio<2629746l, 1l> >’ to type ‘int’
  int period = static_cast<int>(period_in_months(start_date, end_date));

Here are the functions I am using:

auto period_in_months(year_month_day start_date, year_month_day end_time) {
   auto total_months = ((end_time.year() - start_date.year())*12 + (end_time.month() - start_date.month()));
   return (total_months--);
}

double percentage_return(string risk_profile, year_month_day start_date, year_month_day end_date) {
   int period = static_cast<int>(period_in_months(start_date, end_date));
   // do something 
}

I tried using chrono::duration_cast<int>(period_in_months(start_date, end_date) but received the same error.

like image 915
Shravan40 Avatar asked Feb 05 '23 22:02

Shravan40


2 Answers

Here is an article on this subject:

https://github.com/HowardHinnant/date/wiki/Examples-and-Recipes#deltamonths

The article starts with more questions:

Do we want the number of "full months"? Or perhaps we should round to the nearest number of integral months? Or do we want a floating-point representation of months which can show fractional months?

Given two year_month_day objects d1 and d2, here is the difference in months truncated towards zero:

(d2.year()/d2.month() - d1.year()/d1.month())

This returns a chrono duration called months.

The above completely ignores the day field of each date. If you want to take the day field into account and round towards nearest:

auto dp1 = sys_days(d1);
auto dp2 = sys_days(d2);
auto delta = round<months>(dp2-dp1);

There's also a way to get the difference in floating point months shown in the article.

Once you have a chrono duration of any precision, with any representation, one can get the value of that representation out with the .count() member function of chrono::duration:

cout << delta.count() << '\n';
like image 136
Howard Hinnant Avatar answered Feb 08 '23 10:02

Howard Hinnant


Instances of std::chrono::duration template are not (even explicitly) convertible to int. A cast won't work. If you take a look at this reference, you'll find that there is no conversion operator.

From this reference of std::chrono::duration_cast you'll find that

The function does not participate in the overload resolution unless ToDuration is an instance of std::chrono::duration.

int is not an instance of std::chrono::duration, so your second attempt won't work.


If you take a look at the reference of std::chrono::duration again, you'll find the count member function, which

Returns the number of ticks for this duration.

This is what you're looking for. First use chrono::duration_cast to convert the duration to a form that represents the time as an integer with appropriate tick duration (a month in this case), then call count on that duration representation. The duration cast step is unnecessary if your duration is already in the desired representation.

like image 24
eerorika Avatar answered Feb 08 '23 12:02

eerorika