Number of days between two dates C++

I saw examples for C#, Java, but for C++ i cant find solution to calculate how many days between two dates.

For example between 2012-01-24 and 2013-01-08

Thanks!


Solution 1:

This is one way.

#include <iostream>
#include <ctime>

int main()
{
    struct std::tm a = {0,0,0,24,5,104}; /* June 24, 2004 */
    struct std::tm b = {0,0,0,5,6,104}; /* July 5, 2004 */
    std::time_t x = std::mktime(&a);
    std::time_t y = std::mktime(&b);
    if ( x != (std::time_t)(-1) && y != (std::time_t)(-1) )
    {
        double difference = std::difftime(y, x) / (60 * 60 * 24);
        std::cout << std::ctime(&x);
        std::cout << std::ctime(&y);
        std::cout << "difference = " << difference << " days" << std::endl;
    }
    return 0;
}

my output

Thu Jun 24 01:00:00 2004
Mon Jul 05 01:00:00 2004
difference = 11 days

Here is a ref to Original author post

Solution 2:

Convert your dates to integer denoting the number of days since an epoch, then subtract. In this example i chosed Rata Die, an explanation of the algorithm can be found at <http://mysite.verizon.net/aesir_research/date/rata.htm>.

int
rdn(int y, int m, int d) { /* Rata Die day one is 0001-01-01 */
    if (m < 3)
        y--, m += 12;
    return 365*y + y/4 - y/100 + y/400 + (153*m - 457)/5 + d - 306;
}

int days = rdn(2013, 1, 8) - rdn(2012, 1, 24);

Solution 3:

New answer for an old question:

Using this C++11/C++14 header-only date library, you can now write:

#include "date.h"
#include <iostream>

int
main()
{
    using namespace date;
    using namespace std;
    auto x = 2012_y/1/24;
    auto y = 2013_y/1/8;
    cout << x << '\n';
    cout << y << '\n';
    cout << "difference = " << (sys_days{y} - sys_days{x}).count() << " days\n";
}

Which outputs:

2012-01-24
2013-01-08
difference = 350 days

If you don't want to depend on this library, you can write your own, using the same date algorithms that the above date library uses. They are found in this paper: chrono-Compatible Low-Level Date Algorithms. The algorithm from this paper that is being exercised in this example is this one:

// Returns number of days since civil 1970-01-01.  Negative values indicate
//    days prior to 1970-01-01.
// Preconditions:  y-m-d represents a date in the civil (Gregorian) calendar
//                 m is in [1, 12]
//                 d is in [1, last_day_of_month(y, m)]
//                 y is "approximately" in
//                   [numeric_limits<Int>::min()/366, numeric_limits<Int>::max()/366]
//                 Exact range of validity is:
//                 [civil_from_days(numeric_limits<Int>::min()),
//                  civil_from_days(numeric_limits<Int>::max()-719468)]
template <class Int>
constexpr
Int
days_from_civil(Int y, unsigned m, unsigned d) noexcept
{
    static_assert(std::numeric_limits<unsigned>::digits >= 18,
             "This algorithm has not been ported to a 16 bit unsigned integer");
    static_assert(std::numeric_limits<Int>::digits >= 20,
             "This algorithm has not been ported to a 16 bit signed integer");
    y -= m <= 2;
    const Int era = (y >= 0 ? y : y-399) / 400;
    const unsigned yoe = static_cast<unsigned>(y - era * 400);      // [0, 399]
    const unsigned doy = (153*(m + (m > 2 ? -3 : 9)) + 2)/5 + d-1;  // [0, 365]
    const unsigned doe = yoe * 365 + yoe/4 - yoe/100 + doy;         // [0, 146096]
    return era * 146097 + static_cast<Int>(doe) - 719468;
}

See chrono-Compatible Low-Level Date Algorithms for details about how this algorithm works, unit tests for it, and its range of validity.

This algorithm models the proleptic Gregorian calendar, which extends the Gregorian calendar indefinitely, both forwards and backwards. To model other calendars (such as the Julian calendar), you will need other algorithms, such as the ones shown here. Once you have other calendars set up, and synchronized to the same serial epoch (these algorithms use 1970-01-01 Gregorian, which is also the Unix time epoch), you can easily compute the number of days not only between any two dates, but also between any two calendars which you have modeled.

This gives you the freedom of not having to hard-code in a date for the switch from Julian to Gregorian. You just have to know which calendar your input data is referenced against.

Sometimes dates in historical documents that might otherwise be ambiguous are annotated with Old Style / New Style to indicate the Julian or Gregorian calendar respectively.

If you are also concerned about the time of day with your dates, this same date library seamlessly integrates with the <chrono> library for use of hours, minutes, seconds, milliseconds, microseconds and nanoseconds, and with system_clock::now() to get the current date and time.

If you are concerned about time zones, an additional (separate) timezone library is written on top of the date library to handle time zones using the IANA timezone database. If needed, the timezone library also has a facility for computations that include leap seconds.

Solution 4:

you can try the boost date_time library