Difference in days, months and years between two dates
-
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. -
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
-
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.
-
@locinig
But there is no "exact" answer expressed in months and days because of the unclear definition of what constitutes a month? There are going to be various different ways of expressing the answer depending on what exact algorithm you want to use. So it seems to me if you demand "exact" you have to define "exactly" how you want it to work. It seems to me you can express a difference in total number of days accurately/unambiguously, but not with y + m + d. -
@ChrisW67 said in Difference in days, months and years between two dates:
Edit: Removed. Too many failure modes for edge cases.
:)
I don't see any possibility for the "exact" answer the OP asks for once months are involved. Let's take one example: something happens on 30th January. Clearly 1st February is 2 days away. 28th February is what, 29 days away? What about 1st March? Is that 29 days? 1 month 1 day? What about from 10th January to 9th March? 1 month and how many days? And so on....