year duration algorithm in c++

algorithm, c++, duration

Solution

I would use Boost for this, since it already implements what you are looking for:

#include <iostream>
#include <boost/date_time/gregorian/gregorian_types.hpp>
namespace date = boost::gregorian;

int main() {
   date::date_period dp(date::date(2012, 6, 4), date::date(2013, 6, 4));
   long days = dp.length().days();
   std::cout << "Days between dates: " << days << std::endl;

}

If you wanted more precision, then you could use `posix_time` from Boost too:

namespace ptime = boost::posix_time;

...

ptime::ptime t1(date::date(2012, 6, 4), ptime::hours(0));
ptime::ptime t2(date::date(2013, 6, 4), ptime::hours(0));

ptime::time_duration td = t2 - t1;
std::cout << "Milliseconds: " << td.total_milliseconds() << std::endl;

Typically `time_t` is measured in seconds. Therefore, you would just need to call to `td.total_seconds()` to obtain the value that you are looking for.

Problem

I'm making a program that needs the duration (in `time_t`) of a year. In other ways, `time_t` of DD/MM/YYYY + duration = `time_t` of DD/MM/YYYY+1 So it may not always be 365 days (and 29/02/2012 will become 28/02/2013) Here's the algorithm I came with : ``` if YEAR is leap than if we are before the 29th feb' than return 365+1 days else if we are the 29th feb' than return 365-1 days else return 365 days else if YEAR+1 is leap than if we are before or the 28th feb' than return 365 days else return 365+1 days else return 365 days ``` Here, a day is 60 * 60 * 24 seconds This algorithm seems to work. But I was wondering if there were another way to do this without all theses conditions and only 2 possible return values, or just some "trick" to optimize the thing. I tried to increment `tm_year` from the `struct tm` like this : ``` // t is the input time_t struct tm Tm (*localtime(&t)); if (Tm.tm_mon == 2 && Tm.tm_mday == 29) --Tm.tm_mday; ++Tm.tm_year; return mktime(&Tm) - t; ``` But the result isn't what I want, I got -1 hour, or -25... I guess it's because a year is not exactly 365 * 24 * 60 * 60.

Original source