Difference in days, months and years between two dates



  • I have a file with multiple dates in this format(example): 20120512 (yyyy-mm-dd)

    Would basically this: The difference in days, months and years between "20120512" to current date.



  • Take a look at "QDate":http://qt-project.org/doc/qt-5.0/qtcore/qdate.html class, "QDate::currentDate()":http://qt-project.org/doc/qt-5.0/qtcore/qdate.html#currentDate static function.
    Now either use the "Julian Day":https://en.wikipedia.org/wiki/Julian_day concept: "QDate::toJulianDay":http://qt-project.org/doc/qt-5.0/qtcore/qdate.html#toJulianDay function or just count the days between two QDate objects using "QDate::daysTo":http://qt-project.org/doc/qt-5.0/qtcore/qdate.html#daysTo function.



  • Thank yuo Alek.

    I searched the Qt documentation, but unfortunately I could not understand because the documentation is incomplete, without much detail. Do you have any examples?



  • Create the QDate Object using "this":http://qt-project.org/doc/qt-5.0/qtcore/qdate.html#fromString-2. Hope this can be your start



  • @ QDate currDate(QDate::fromString("20090512", "yyyyMMdd"));

    qDebug() << currDate.toJulianDay();@
    

    What i'm doing wrong?

    This returns: 2454964;



  • Per "QDate - Range of valid dates":http://qt-project.org/doc/qt-5.0/qtcore/qdate.html#range-of-valid-dates:

    bq. Dates are stored internally as a Julian Day number, an integer count of every day in a contiguous range, with 24 November 4714 BCE in the Gregorian calendar being Julian Day 0 (1 January 4713 BCE in the Julian calendar). As well as being an efficient and accurate way of storing an absolute date, it is suitable for converting a Date into other calendar systems such as Hebrew, Islamic or Chinese. The Julian Day number can be obtained using QDate::toJulianDay() and can be set using QDate::fromJulianDay().
    The range of dates able to be stored by QDate as a Julian Day number is for technical reasons limited to between -784350574879 and 784354017364, which means from before 2 billion BCE to after 2 billion CE.

    This - the number 2454964 - is precisely the difference in days between 24 November 4714 BCE and 12 May 2009 CE.

    What you need, though, is to create two QDate objects - one from your character strings using QDate::fromString function, the other from the current date QDate::currentDate static function, and then calculate the difference in days by subtracting their julian days obtained from QDate::toJulianDay function. Is it clear enough?



  • Hi, as Alek say,

    but, is this code right?
    @QDate currDate(QDate::fromString("20090512", "yyyyMMdd"));
    QDate firstDay(QDate::fromString("01010001", "ddMMyyyy"));

    //Searched diff, in days.
    int days = QDate::currentDate().toJulianDay() - currDate.toJulianDay();
    QDate diffDay = QDate::fromJulianDay(QDate::currentDate().toJulianDay() - currDate.toJulianDay());

    //Days form first day (24 November 4714 BCE) and 01/01/0001
    int ceroDay = firstDay.toJulianDay();

    //Searched diff in date format
    QDate calcDay = QDate::fromJulianDay(days + ceroDay - 366);

    qDebug() << "diff in date format:" << calcDay.toString("yyyy-MM-dd");
    qDebug() << "years:" << calcDay.year();
    qDebug() << "months:" << calcDay.month();
    qDebug() << "days:" << calcDay.day();
    @

    Output:
    @Diff. days: 1485 , from day 1: 1721426
    diff in date format: "0004-01-25"
    years: 4
    months: 1
    days: 25
    @
    Regards



  • SergioDanielG, your code seems to be incorrect, looking at the result (one-off error with the months?).

    The fact that OP wants months and years out of the difference, which are of irregular length, makes the matter difficult and possibly broken in some instances (leap years, leap days, negative numbers like in the "2012-06-05 - 20090512" example). Here's my try, rough around the edges...

    @#include <QString>
    #include <QDate>
    #include <QDebug>

    int main()
    {
    QString source = "20090512";
    QDate sourceDate = QDate::fromString(source, "yyyyMMdd");

    qint64 daysBetween = QDate::currentDate().toJulianDay() - sourceDate.toJulianDay();
    QDate difference = QDate::fromJulianDay(daysBetween);
    
    QDate firstDate = QDate::fromJulianDay(0);
    
    int years = difference.year() - firstDate.year();
    int months = difference.month() - firstDate.month();
    int days = difference.day() - firstDate.day();
    
    // TODO: check if a number is negative and if so, normalize
    
    qDebug() << QDate::currentDate().toString("yy-MM-dd");
    qDebug() << sourceDate.toString("yy-MM-dd");
    qDebug() << daysBetween;
    qDebug() << QString("%1 years, %2 months and %3 days").arg(years).arg(months).arg(days);
    

    }
    @

    Output:
    @"13-06-05"
    "09-05-12"
    1485
    "4 years, 1 months and -6 days"
    @



  • Hi Alek. Thanks for reply. This is a little confused to me, but I think, now I understand.
    In my code, output is 4 years, 1 month and 25 days, thats is incorrect because 1485 days are 4.0685 years (1485/365), 4 years and 25 days (1485 - 365*4)

    In my code, I tried to represent (incorrectly) day 1485º, incorrectly because we are talking about days and not about some date.
    Thanks again and I hope usefull to l3e0wulf.
    Regards



  • And what about to use QDate::daysTo()?

    From the documentation:
    @ QDate d1(1995, 5, 17); // May 17, 1995
    QDate d2(1995, 5, 20); // May 20, 1995
    d1.daysTo(d2); // returns 3
    d2.daysTo(d1); // returns -3@



  • francescmm, that is indeed another way for checking the difference in days, but still you need to handle QDate object from Julian Days so as to represent the difference as years, months and days like the OP wanted to.



  • Hi guys! i was looking for a good solution to count time elapsed between two dates, but didn't found that I really like, but Alek Śmierciak's code was the best i found, but the problem is those negatives digits which can often occur. this is a bit embarrassing. so I work it out, in found a better aproach, and simpler. so i wanted to share it!

    @
    QDate first(1,1,1);
    QDate sourceDate(1990,1,22);
    QDate today= QDate::currentDate();
    int days= sourceDate.daysTo(today);
    first= first.addDays(days);
    int day= first.day()-1;
    int month= first.month()-1;
    int year= first.year()-1;

    QString len= QString::number(year)+" years " + QString::number(month)+" month " + QString::number(day)+" days";
    

    qDebug() << len;
    @

    I tested it, and I think everything is okay, but if you notice any error, please let me know.



  • @top-dog It is not working properly, take for example difference between 26/11/2015 and 25/11/2016.
    Adding a working algorithm, let me know if you find any troubles:

    static int increment[12] = { 1, -2, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 };
    
    int daysInc = 0;
    if (to.day() - from.day() < 0)
    {
        int month = to.month() - 2; // -1 from zero, -1 previous month.
        if (month < 0)
            month = 11; // Previous month is December.
        daysInc = increment[month];
        if ( (month == 1) && (to.year()%4 == 0) )
            daysInc++; // Increment days for leap year.
    }
    
    int total1 = from.year()*360 + from.month()*30 + from.day();
    int total2 = to.year()*360 + to.month()*30 + to.day();
    int diff = total2 - total1;
    int years = diff/360;
    int months = (diff - years*360)/30;
    int days = diff - years*360 - months*30 + daysInc;
    
    // Extra calculation when we can pass one month instead of 30 days.
    if (from.day() == 1 && to.day() == 31) {
        result.months--;
        result.days = 30;
    }


  • Difference between two QDateTime in days, months and years.
    Takes into account leap year.

    QDateTime beginDate(QDate(2020, 2, 21), QTime(8, 00, 0));//=QDateTime::currentDateTime(); 
    QDateTime expireDate(QDate(2021, 2, 20), QTime(8, 00, 0));
    int y=0, m=0, d=0;
    if(beginDate.daysTo(expireDate) >= 0)
    {
        y=expireDate.date().year()-beginDate.date().year();
        if((m=expireDate.date().month()-beginDate.date().month())<0) 
        {
            y--;
            m+=12;
        }
        if((d=expireDate.date().day()-beginDate.date().day())<0) 
        {
            if(--m < 0)
            {
                y--;
                m+=12;
            }
            d+=beginDate.date().daysInMonth(); 
        }
        qDebug()<<y<<m<<d;
      }
    

    Result: 0 years 11months 28 days = 365 days difference of leap year.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.