From: Vadim Zeitlin Date: Thu, 17 Dec 2009 17:51:12 +0000 (+0000) Subject: Correct wxDateTime::GetWeekOfMonth() for days in the beginning of January. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/404013f849619f420c671dab801e1aa4b2749836 Correct wxDateTime::GetWeekOfMonth() for days in the beginning of January. This function was implemented in terms of GetWeekOfYear() which made it tricky to get it right as GetWeekOfYear() can, correctly, return week number for the previous year for the first days of January (and also from the next one for the last days of December). Replace this implementation with a simple one directly counting the number of weeks since the first of the month, this seems to be much simpler and does pass the new unit test case which the old version failed. Also make the unit test failures more informative by using WX_ASSERT_EQUAL_MESSAGE() instead of CPPUNIT_ASSERT_EQUAL(). See #11561. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62916 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index e20225d593..3f036e61da 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -2054,16 +2054,22 @@ wxDateTime::wxDateTime_t wxDateTime::GetWeekOfMonth(wxDateTime::WeekFlags flags, const TimeZone& tz) const { Tm tm = GetTm(tz); - wxDateTime dtMonthStart = wxDateTime(1, tm.mon, tm.year); - int nWeek = GetWeekOfYear(flags) - dtMonthStart.GetWeekOfYear(flags) + 1; - if ( nWeek < 0 ) + const wxDateTime dateFirst = wxDateTime(1, tm.mon, tm.year); + const wxDateTime::WeekDay wdFirst = dateFirst.GetWeekDay(); + + if ( flags == Default_First ) { - // this may happen for January when Jan, 1 is the last week of the - // previous year - nWeek += IsLeapYear(tm.year - 1) ? 53 : 52; + flags = GetCountry() == USA ? Sunday_First : Monday_First; } - return (wxDateTime::wxDateTime_t)nWeek; + // compute offset of dateFirst from the beginning of the week + int firstOffset; + if ( flags == Sunday_First ) + firstOffset = wdFirst - Sun; + else + firstOffset = wdFirst == Sun ? DAYS_PER_WEEK - 1 : wdFirst - Mon; + + return (wxDateTime::wxDateTime_t)((tm.mday - 1 + firstOffset)/7 + 1); } wxDateTime& wxDateTime::SetToYearDay(wxDateTime::wxDateTime_t yday) diff --git a/tests/datetime/datetimetest.cpp b/tests/datetime/datetimetest.cpp index 6cddf64142..4731265645 100644 --- a/tests/datetime/datetimetest.cpp +++ b/tests/datetime/datetimetest.cpp @@ -555,6 +555,8 @@ for n in range(20): { { 16, wxDateTime::Oct, 1942, 0, 0, 0, 0.0, wxDateTime::Inv_WeekDay, 0 }, 42, 3, 3, 289 }, { { 30, wxDateTime::Dec, 2003, 0, 0, 0, 0.0, wxDateTime::Inv_WeekDay, 0 }, 1, 5, 5, 364 }, { { 2, wxDateTime::Jan, 2004, 0, 0, 0, 0.0, wxDateTime::Inv_WeekDay, 0 }, 1, 1, 1, 2 }, + { { 5, wxDateTime::Jan, 2010, 0, 0, 0, 0.0, wxDateTime::Inv_WeekDay, 0 }, 1, 2, 2, 5 }, + { { 3, wxDateTime::Jan, 2011, 0, 0, 0, 0.0, wxDateTime::Inv_WeekDay, 0 }, 1, 2, 2, 3 }, }; for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ ) @@ -570,10 +572,14 @@ for n in range(20): wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First), dnum = dt.GetDayOfYear(); - CPPUNIT_ASSERT_EQUAL( wn.dnum, dnum ); - CPPUNIT_ASSERT_EQUAL( wn.wmon, wmon ); - CPPUNIT_ASSERT_EQUAL( wn.wmon2, wmon2 ); - CPPUNIT_ASSERT_EQUAL( wn.week, week ); + WX_ASSERT_EQUAL_MESSAGE( ("day of year for %s", d.Format()), + wn.dnum, dnum ); + WX_ASSERT_EQUAL_MESSAGE( ("week of month (Monday) for %s", d.Format()), + wn.wmon, wmon ); + WX_ASSERT_EQUAL_MESSAGE( ("week of month (Sunday) for %s", d.Format()), + wn.wmon2, wmon2 ); + WX_ASSERT_EQUAL_MESSAGE( ("week of year for %s", d.Format()), + wn.week, week ); int year = d.year; if ( week == 1 && d.month != wxDateTime::Jan )