From: Vadim Zeitlin Date: Sun, 3 Feb 2008 13:04:56 +0000 (+0000) Subject: added wxDateTime::FormatISOCombined() and ParseISODate/Time/Combined() X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/f3f2e255b420523408496ba01844f9854373834e added wxDateTime::FormatISOCombined() and ParseISODate/Time/Combined() git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@51516 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/changes.txt b/docs/changes.txt index 0e5431fe26..79bca35924 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -194,6 +194,7 @@ All: - Use UTF-8 for Unicode data in wxIPC classes (Anders Larsen) - Added support for user-defined types to wxConfig (Marcin Wojdyr). - Added wxJoin() and wxSplit() functions (Francesco Montorsi). +- Added wxDateTime::FormatISOCombined() and ParseISODate/Time/Combined() - Added wxMutex::LockTimeout() (Aleksandr Napylov). - Added wxMemoryInputStream(wxInputStream&) ctor (Stas Sergeev). - Implemented wxMemoryInputStream::CanRead(). diff --git a/docs/latex/wx/datetime.tex b/docs/latex/wx/datetime.tex index dd67d84bd7..3fa45268da 100644 --- a/docs/latex/wx/datetime.tex +++ b/docs/latex/wx/datetime.tex @@ -331,9 +331,10 @@ date and time representations for the current locale ( \helpref{FormatDate}{wxdatetimeformatdate} and \helpref{FormatTime}{wxdatetimeformattime}), using the international standard representation defined by ISO 8601 ( -\helpref{FormatISODate}{wxdatetimeformatisodate} and -\helpref{FormatISOTime}{wxdatetimeformatisotime}) or by specifying any format -at all and using \helpref{Format}{wxdatetimeformat} directly. +\helpref{FormatISODate}{wxdatetimeformatisodate}, +\helpref{FormatISOTime}{wxdatetimeformatisotime} and +\helpref{FormatISOCombined}{wxdatetimeformatisocombined}) or by specifying any +format at all and using \helpref{Format}{wxdatetimeformat} directly. The conversions from text are more interesting, as there are much more possibilities to care about. The simplest cases can be taken care of with @@ -363,14 +364,18 @@ char pointer is also returned for backwards compatibility but there is also an additional argument of wxString::const\_iterator type in which, if it is not \NULL, an iterator pointing to the end of the scanned string part is returned. -\helpref{ParseRfc822Date}{wxdatetimeparserfc822date}\\ \helpref{ParseFormat}{wxdatetimeparseformat}\\ \helpref{ParseDateTime}{wxdatetimeparsedatetime}\\ \helpref{ParseDate}{wxdatetimeparsedate}\\ \helpref{ParseTime}{wxdatetimeparsetime}\\ +\helpref{ParseISODate}{wxdatetimeparseisodate}\\ +\helpref{ParseISOTime}{wxdatetimeparseisotime}\\ +\helpref{ParseISOCombined}{wxdatetimeparseisocombined}\\ +\helpref{ParseRfc822Date}{wxdatetimeparserfc822date}\\ \helpref{Format}{wxdatetimeformat}\\ \helpref{FormatDate}{wxdatetimeformatdate}\\ \helpref{FormatTime}{wxdatetimeformattime}\\ +\helpref{FormatISOCombined}{wxdatetimeformatisocombined}\\ \helpref{FormatISODate}{wxdatetimeformatisodate}\\ \helpref{FormatISOTime}{wxdatetimeformatisotime} @@ -1279,6 +1284,35 @@ Returns {\tt NULL} if the conversion failed, otherwise return the pointer to the character which stopped the scan. +\membersection{wxDateTime::ParseISODate}\label{wxdatetimeparseisodate} + +\func{bool}{ParseISODate}{\param{const wxString\& }{date}} + +This function parses the date in ISO 8601 format (YYYY-MM-DD). + +Returns \true if the entire string was parsed successfully, \false otherwise. + + +\membersection{wxDateTime::ParseISOTime}\label{wxdatetimeparseisotime} + +\func{bool}{ParseISOTime}{\param{const wxString\& }{date}} + +This function parses the time in ISO 8601 format (HH:MM:SS). + +Returns \true if the entire string was parsed successfully, \false otherwise. + + +\membersection{wxDateTime::ParseISOCombined}\label{wxdatetimeparseisocombined} + +\func{bool}{ParseISOCombined}{\param{const wxString\& }{date}, \param{char }{sep = 'T'}} + +This function parses the string containing the date and time in ISO 8601 +combined format (YYYY-MM-DDTHH:MM:SS). The separator between the date and time +parts must be equal to \arg{sep} for the function to succeed. + +Returns \true if the entire string was parsed successfully, \false otherwise. + + \membersection{wxDateTime::Format}\label{wxdatetimeformat} \constfunc{wxString }{Format}{\param{const wxChar *}{format = wxDefaultDateTimeFormat}, \param{const TimeZone\& }{tz = Local}} @@ -1311,6 +1345,23 @@ Identical to calling \helpref{Format()}{wxdatetimeformat} with {\tt "\%X"} argument (which means `preferred time representation for the current locale'). +\membersection{wxDateTime::FormatISOCombined}\label{wxdatetimeformatisocombined} + +\constfunc{wxString}{FormatISOCombined}{\param{char }{sep = 'T'}} + +Returns the combined date-time representation in the ISO 8601 format +(YYYY-MM-DDTHH:MM:SS). The \arg{sep} parameter default value produces the +result exactly corresponding to the ISO standard, but it can also be useful to +use a space as seprator if a more human-readable combined date-time +representation is needed. + +\wxheading{See also} + +\helpref{FormatISODate}{wxdatetimeformatisodate},\\ +\helpref{FormatISOTime}{wxdatetimeformatisotime},\\ +\helpref{ParseISOCombined}{wxdatetimeparseisocombined} + + \membersection{wxDateTime::FormatISODate}\label{wxdatetimeformatisodate} \constfunc{wxString }{FormatISODate}{\void} diff --git a/include/wx/datetime.h b/include/wx/datetime.h index 5aac2b16d4..c648073ed8 100644 --- a/include/wx/datetime.h +++ b/include/wx/datetime.h @@ -1109,7 +1109,7 @@ public: } const char *ParseFormat(const char *date, - const wxString& format = L"%c", + const wxString& format = "%c", const wxDateTime& dateDef = wxDefaultDateTime) { return ParseFormat(wxString(date), format, dateDef); @@ -1122,6 +1122,29 @@ public: return ParseFormat(wxString(date), wxString(format), dateDef); } + // parse a string containing date, time or both in ISO 8601 format + // + // notice that these functions are new in wx 3.0 and so we don't + // provide compatibility overloads for them + bool ParseISODate(const wxString& date) + { + const wxStringCharType *p = ParseFormat(date, wxS("%Y-%m-%d")); + return p && !*p; + } + + bool ParseISOTime(const wxString& date) + { + const wxStringCharType *p = ParseFormat(date, wxS("%H:%M:%S")); + return p && !*p; + } + + bool ParseISOCombined(const wxString& date, char sep = 'T') + { + const wxString fmt = wxS("%Y-%m-%d") + wxString(sep) + wxS("%H:%M:%S"); + const wxStringCharType *p = ParseFormat(date, fmt.wx_str()); + return p && !*p; + } + // parse a string containing the date/time in "free" format, this // function will try to make an educated guess at the string contents const char *ParseDateTime(const wxString& datetime, @@ -1191,15 +1214,20 @@ public: wxString Format(const wxString& format = wxDefaultDateTimeFormat, const TimeZone& tz = Local) const; // preferred date representation for the current locale - wxString FormatDate() const { return Format(_T("%x")); } + wxString FormatDate() const { return Format(wxS("%x")); } // preferred time representation for the current locale - wxString FormatTime() const { return Format(_T("%X")); } + wxString FormatTime() const { return Format(wxS("%X")); } // returns the string representing the date in ISO 8601 format // (YYYY-MM-DD) - wxString FormatISODate() const { return Format(_T("%Y-%m-%d")); } + wxString FormatISODate() const { return Format(wxS("%Y-%m-%d")); } // returns the string representing the time in ISO 8601 format // (HH:MM:SS) - wxString FormatISOTime() const { return Format(_T("%H:%M:%S")); } + wxString FormatISOTime() const { return Format(wxS("%H:%M:%S")); } + // return the combined date time representation in ISO 8601 format; the + // separator character should be 'T' according to the standard but it + // can also be useful to set it to ' ' + wxString FormatISOCombined(char sep = 'T') const + { return FormatISODate() + sep + FormatISOTime(); } // implementation // ------------------------------------------------------------------------ diff --git a/tests/datetime/datetimetest.cpp b/tests/datetime/datetimetest.cpp index 9954829477..3a2db4a287 100644 --- a/tests/datetime/datetimetest.cpp +++ b/tests/datetime/datetimetest.cpp @@ -27,7 +27,7 @@ // need this to be able to use CPPUNIT_ASSERT_EQUAL with wxDateTime objects static std::ostream& operator<<(std::ostream& ostr, const wxDateTime& dt) { - ostr << dt.FormatISODate() << " " << dt.FormatISOTime(); + ostr << dt.FormatISOCombined(' '); return ostr; } @@ -188,6 +188,7 @@ private: CPPUNIT_TEST( TestTimeTicks ); CPPUNIT_TEST( TestParceRFC822 ); CPPUNIT_TEST( TestDateParse ); + CPPUNIT_TEST( TestDateParseISO ); CPPUNIT_TEST( TestDateTimeParse ); CPPUNIT_TEST( TestTimeArithmetics ); CPPUNIT_TEST( TestDSTBug ); @@ -205,6 +206,7 @@ private: void TestTimeTicks(); void TestParceRFC822(); void TestDateParse(); + void TestDateParseISO(); void TestDateTimeParse(); void TestTimeArithmetics(); void TestDSTBug(); @@ -838,6 +840,80 @@ void DateTimeTestCase::TestDateParse() } } +void DateTimeTestCase::TestDateParseISO() +{ + static const struct + { + const char *str; + Date date; // NB: this should be in UTC + bool good; + } parseTestDates[] = + { + { "2006-03-21", { 21, wxDateTime::Mar, 2006 }, true }, + { "1976-02-29", { 29, wxDateTime::Feb, 1976 }, true }, + { "0006-03-31", { 31, wxDateTime::Mar, 6 }, true }, + + // some invalid ones too + { "2006:03:31" }, + { "31/04/06" }, + { "bloordyblop" }, + { "" }, + }; + + static const struct + { + const char *str; + wxDateTime::wxDateTime_t hour, min, sec; + bool good; + } parseTestTimes[] = + { + { "13:42:17", 13, 42, 17, true }, + { "02:17:01", 2, 17, 1, true }, + + // some invalid ones too + { "66:03:31" }, + { "31/04/06" }, + { "bloordyblop" }, + { "" }, + }; + + for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ ) + { + wxDateTime dt; + if ( dt.ParseISODate(parseTestDates[n].str) ) + { + CPPUNIT_ASSERT( parseTestDates[n].good ); + + CPPUNIT_ASSERT_EQUAL( parseTestDates[n].date.DT(), dt ); + + for ( size_t m = 0; m < WXSIZEOF(parseTestTimes); m++ ) + { + wxString dtCombined; + dtCombined << parseTestDates[n].str + << 'T' + << parseTestTimes[m].str; + + if ( dt.ParseISOCombined(dtCombined) ) + { + CPPUNIT_ASSERT( parseTestTimes[m].good ); + + CPPUNIT_ASSERT_EQUAL( parseTestTimes[m].hour, dt.GetHour()) ; + CPPUNIT_ASSERT_EQUAL( parseTestTimes[m].min, dt.GetMinute()) ; + CPPUNIT_ASSERT_EQUAL( parseTestTimes[m].sec, dt.GetSecond()) ; + } + else // failed to parse combined date/time + { + CPPUNIT_ASSERT( !parseTestTimes[m].good ); + } + } + } + else // failed to parse + { + CPPUNIT_ASSERT( !parseTestDates[n].good ); + } + } +} + void DateTimeTestCase::TestDateTimeParse() { static const struct ParseTestData