Fix bugs in the recently added wxDateTime::DiffAsDateSpan().
Correct the test for negative spans less than a month and use the correct month for computing the number of days in it. Also add unit tests for problematic cases. Closes #14704. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72616 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1612,25 +1612,34 @@ wxDateSpan wxDateTime::DiffAsDateSpan(const wxDateTime& dt) const
|
|||||||
inv = -1;
|
inv = -1;
|
||||||
|
|
||||||
int y = GetYear() - dt.GetYear();
|
int y = GetYear() - dt.GetYear();
|
||||||
|
int m = GetMonth() - dt.GetMonth();
|
||||||
|
int d = GetDay() - dt.GetDay();
|
||||||
|
|
||||||
// If month diff is negative, dt is the year before, so decrease year
|
// If month diff is negative, dt is the year before, so decrease year
|
||||||
// and set month diff to its inverse, e.g. January - December should be 1,
|
// and set month diff to its inverse, e.g. January - December should be 1,
|
||||||
// not -11.
|
// not -11.
|
||||||
int m = GetMonth() - dt.GetMonth();
|
if ( m * inv < 0 || (m == 0 && d * inv < 0))
|
||||||
if ( m * inv < 0 )
|
|
||||||
{
|
{
|
||||||
m += inv * MONTHS_IN_YEAR;
|
m += inv * MONTHS_IN_YEAR;
|
||||||
y -= inv;
|
y -= inv;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same logic for days as for months above. Use number of days in month
|
// Same logic for days as for months above.
|
||||||
// from the month which end date we're crossing.
|
|
||||||
int d = GetDay() - dt.GetDay();
|
|
||||||
if ( d * inv < 0 )
|
if ( d * inv < 0 )
|
||||||
{
|
{
|
||||||
d += inv * wxDateTime::GetNumberOfDays(
|
// Use number of days in month from the month which end date we're
|
||||||
inv > 0 ? dt.GetMonth() : GetMonth(),
|
// crossing. That is month before this for positive diff, and this
|
||||||
inv > 0 ? dt.GetYear() : GetMonth());
|
// month for negative diff.
|
||||||
|
// If we're on january and using previous month, we get december
|
||||||
|
// previous year, but don't care, december has same amount of days
|
||||||
|
// every year.
|
||||||
|
wxDateTime::Month monthfordays = GetMonth();
|
||||||
|
if (inv > 0 && monthfordays == wxDateTime::Jan)
|
||||||
|
monthfordays = wxDateTime::Dec;
|
||||||
|
else if (inv > 0)
|
||||||
|
monthfordays = static_cast<wxDateTime::Month>(monthfordays - 1);
|
||||||
|
|
||||||
|
d += inv * wxDateTime::GetNumberOfDays(monthfordays, GetYear());
|
||||||
m -= inv;
|
m -= inv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1214,6 +1214,31 @@ void DateTimeTestCase::TestTimeArithmetics()
|
|||||||
CPPUNIT_ASSERT_EQUAL( dt1, dt2 + 2*span );
|
CPPUNIT_ASSERT_EQUAL( dt1, dt2 + 2*span );
|
||||||
CPPUNIT_ASSERT_EQUAL( span, dt1.DiffAsDateSpan(dt) );
|
CPPUNIT_ASSERT_EQUAL( span, dt1.DiffAsDateSpan(dt) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// More date span arithmetics tests
|
||||||
|
wxDateTime dtd1(5, wxDateTime::Jun, 1998);
|
||||||
|
wxDateTime dtd2(6, wxDateTime::Aug, 1999);
|
||||||
|
|
||||||
|
// All parts in dtd2 is after dtd1
|
||||||
|
CPPUNIT_ASSERT_EQUAL( wxDateSpan(1, 2, 0, 1), dtd2.DiffAsDateSpan(dtd1) );
|
||||||
|
|
||||||
|
// Year and month after, day earlier, so no full month
|
||||||
|
// Jul has 31 days, so it's 31 - 5 + 4 = 30, or 4w 2d
|
||||||
|
dtd2.Set(4, wxDateTime::Aug, 1999);
|
||||||
|
CPPUNIT_ASSERT_EQUAL( wxDateSpan(1, 1, 4, 2), dtd2.DiffAsDateSpan(dtd1) );
|
||||||
|
|
||||||
|
// Year and day after, month earlier, so no full year, but same day diff as
|
||||||
|
// first example
|
||||||
|
dtd2.Set(6, wxDateTime::May, 1999);
|
||||||
|
CPPUNIT_ASSERT_EQUAL( wxDateSpan(0, 11, 0, 1), dtd2.DiffAsDateSpan(dtd1) );
|
||||||
|
|
||||||
|
// Year after, month and day earlier, so no full month and no full year
|
||||||
|
// April has 30 days, so it's 30 - 5 + 4 = 29, or 4w 1d
|
||||||
|
dtd2.Set(4, wxDateTime::May, 1999);
|
||||||
|
CPPUNIT_ASSERT_EQUAL( wxDateSpan(0, 10, 4, 1), dtd2.DiffAsDateSpan(dtd1) );
|
||||||
|
|
||||||
|
// And a reverse. Now we should use days in Jun (again 30 => 4w 1d)
|
||||||
|
CPPUNIT_ASSERT_EQUAL( wxDateSpan(0, -10, -4, -1), dtd1.DiffAsDateSpan(dtd2) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void DateTimeTestCase::TestDSTBug()
|
void DateTimeTestCase::TestDSTBug()
|
||||||
|
Reference in New Issue
Block a user