inv = -1;
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
// and set month diff to its inverse, e.g. January - December should be 1,
// not -11.
- int m = GetMonth() - dt.GetMonth();
- if ( m * inv < 0 )
+ if ( m * inv < 0 || (m == 0 && d * inv < 0))
{
m += inv * MONTHS_IN_YEAR;
y -= inv;
}
- // Same logic for days as for months above. Use number of days in month
- // from the month which end date we're crossing.
- int d = GetDay() - dt.GetDay();
+ // Same logic for days as for months above.
if ( d * inv < 0 )
{
- d += inv * wxDateTime::GetNumberOfDays(
- inv > 0 ? dt.GetMonth() : GetMonth(),
- inv > 0 ? dt.GetYear() : GetMonth());
+ // Use number of days in month from the month which end date we're
+ // crossing. That is month before this for positive diff, and this
+ // 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;
}
CPPUNIT_ASSERT_EQUAL( dt1, dt2 + 2*span );
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()