From 77dd7daad2df0faac2b4e846ac9bb6aff588278c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 1 Oct 2012 09:55:05 +0000 Subject: [PATCH] Add wxDateTime::DiffAsDateSpan(). This method returns the difference between the dates as wxDateSpan, unlike the existing Subtract() and overloaded operator-() that return wxTimeSpan. Closes #14704. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72600 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + include/wx/datetime.h | 2 ++ interface/wx/datetime.h | 9 ++++++++ src/common/datetime.cpp | 41 +++++++++++++++++++++++++++++++++ tests/datetime/datetimetest.cpp | 1 + tests/testdate.h | 11 +++++++++ 6 files changed, 65 insertions(+) diff --git a/docs/changes.txt b/docs/changes.txt index f6c12193c9..8bcc67f1e9 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -535,6 +535,7 @@ All: - Fix compilation of wxHash{Map,Set} with g++ 4.7 (Nathan Ridge). - Fix posting large amounts of data in wxHTTP (Platonides). - Add wxFile::ReadAll() for consistency with wxFFile. +- Add wxDateTime::DiffAsDateSpan() (jonasr). - Added Nepali translation (Him Prasad Gautam). All (GUI): diff --git a/include/wx/datetime.h b/include/wx/datetime.h index 3420179e5a..caeae26bda 100644 --- a/include/wx/datetime.h +++ b/include/wx/datetime.h @@ -1063,6 +1063,8 @@ public: inline wxTimeSpan Subtract(const wxDateTime& dt) const; inline wxTimeSpan operator-(const wxDateTime& dt2) const; + wxDateSpan DiffAsDateSpan(const wxDateTime& dt) const; + // conversion to/from text // ------------------------------------------------------------------------ diff --git a/interface/wx/datetime.h b/interface/wx/datetime.h index 0ad913cbd7..1785f392cc 100644 --- a/interface/wx/datetime.h +++ b/interface/wx/datetime.h @@ -846,6 +846,15 @@ public: them as a wxTimeSpan. */ wxTimeSpan Subtract(const wxDateTime& dt) const; + /** + Returns the difference between this object and @a dt as a wxDateSpan. + + This method allows to find the number of entire years, months, weeks and + days between @a dt and this date. + + @since 2.9.5 + */ + wxDateSpan DiffAsDateSpan(const wxDateTime& dt) const; /** Adds the given date span to this object. diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index a2ca5d4ed8..462347d7d6 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -1602,6 +1602,47 @@ wxDateTime& wxDateTime::Add(const wxDateSpan& diff) return *this; } +wxDateSpan wxDateTime::DiffAsDateSpan(const wxDateTime& dt) const +{ + wxASSERT_MSG( IsValid() && dt.IsValid(), wxT("invalid wxDateTime")); + + // If dt is larger than this, calculations below needs to be inverted. + int inv = 1; + if ( dt > *this ) + inv = -1; + + int y = GetYear() - dt.GetYear(); + + // 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 ) + { + 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(); + if ( d * inv < 0 ) + { + d += inv * wxDateTime::GetNumberOfDays( + inv > 0 ? dt.GetMonth() : GetMonth(), + inv > 0 ? dt.GetYear() : GetMonth()); + m -= inv; + } + + int w = d / DAYS_PER_WEEK; + + // Remove weeks from d, since wxDateSpan only keep days as the ones + // not in complete weeks + d -= w * DAYS_PER_WEEK; + + return wxDateSpan(y, m, w, d); +} + // ---------------------------------------------------------------------------- // Weekday and monthday stuff // ---------------------------------------------------------------------------- diff --git a/tests/datetime/datetimetest.cpp b/tests/datetime/datetimetest.cpp index 76f82355b4..00a76af0ea 100644 --- a/tests/datetime/datetimetest.cpp +++ b/tests/datetime/datetimetest.cpp @@ -1212,6 +1212,7 @@ void DateTimeTestCase::TestTimeArithmetics() CPPUNIT_ASSERT_EQUAL( dt, dt1 - span ); CPPUNIT_ASSERT_EQUAL( dt, dt2 + span ); CPPUNIT_ASSERT_EQUAL( dt1, dt2 + 2*span ); + CPPUNIT_ASSERT_EQUAL( span, dt1.DiffAsDateSpan(dt) ); } } diff --git a/tests/testdate.h b/tests/testdate.h index 5d28568da6..4a40967159 100644 --- a/tests/testdate.h +++ b/tests/testdate.h @@ -20,6 +20,17 @@ inline std::ostream& operator<<(std::ostream& ostr, const wxDateTime& dt) return ostr; } +// need this to be able to use CPPUNIT_ASSERT_EQUAL with wxDateSpan objects +inline std::ostream& operator<<(std::ostream& ostr, const wxDateSpan& span) +{ + ostr << span.GetYears() << "Y, " + << span.GetMonths() << "M, " + << span.GetWeeks() << "W, " + << span.GetDays() << "D"; + + return ostr; +} + WX_CPPUNIT_ALLOW_EQUALS_TO_INT(wxDateTime::wxDateTime_t) #endif // _WX_TESTS_TESTDATE_H_ -- 2.47.2