From 8888d9710f2b747762790f8a06009af251180ee8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 30 Sep 2007 19:11:36 +0000 Subject: [PATCH] cleaned up and significantly simiplied Format() handling of %c and %x formats and fixed an assert failure in UTF-8 build due to the use of invalid Unicode characters such as -1 git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@48996 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/datetime.cpp | 76 +++++++++++++---------------------------- 1 file changed, 24 insertions(+), 52 deletions(-) diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 026bae109d..06dd58caa6 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -2461,7 +2461,7 @@ wxString wxDateTime::Format(const wxString& format, const TimeZone& tz) const // will change if one of these years is leap and the other one // is not! { - // find the YEAR: normally, for any year X, Jan 1 or the + // find the YEAR: normally, for any year X, Jan 1 of the // year X + 28 is the same weekday as Jan 1 of X (because // the weekday advances by 1 for each normal X and by 2 // for each leap X, hence by 5 every 4 years or by 35 @@ -2503,41 +2503,15 @@ wxString wxDateTime::Format(const wxString& format, const TimeZone& tz) const nLostWeekDays += year++ % 4 ? 1 : 2; } - // Keep year below 2000 so the 2digit year number - // can never match the month or day of the month - if (year>=2000) year-=28; - // at any rate, we couldn't go further than 1988 + 9 + 28! - wxASSERT_MSG( year < 2030, + // finally move the year below 2000 so that the 2-digit + // year number can never match the month or day of the + // month when we do the replacements below + if ( year >= 2000 ) + year -= 28; + + wxASSERT_MSG( year >= 1970 && year < 2000, _T("logic error in wxDateTime::Format") ); - wxString strYear, strYear2; - strYear.Printf(_T("%d"), year); - strYear2.Printf(_T("%d"), year % 100); - - // find four strings not occurring in format (this is surely - // not the optimal way of doing it... improvements welcome!) - wxString fmt2 = format; - wxString replacement,replacement2,replacement3,replacement4; - for (int rnr=1; rnr<5 ; rnr++) - { - wxString r = (wxChar)-rnr; - while ( fmt2.Find(r) != wxNOT_FOUND ) - { - r << (wxChar)-rnr; - } - - switch (rnr) - { - case 1: replacement=r; break; - case 2: replacement2=r; break; - case 3: replacement3=r; break; - case 4: replacement4=r; break; - } - } - // replace all occurrences of year with it - bool wasReplaced = fmt2.Replace(strYear, replacement) > 0; - // evaluation order ensures we always attempt the replacement. - wasReplaced = (fmt2.Replace(strYear2, replacement2) > 0) || wasReplaced; // use strftime() to format the same date but in supported // year @@ -2561,25 +2535,23 @@ wxString wxDateTime::Format(const wxString& format, const TimeZone& tz) const : _T("%x"), &tmAdjusted); - // now replace the occurrence of 1999 with the real year - // we do this in two stages to stop the 2 digit year - // matching any substring of the 4 digit year. - // Any day,month hours and minutes components should be safe due - // to ensuring the range of the years. - wxString strYearReal, strYearReal2; - strYearReal.Printf(_T("%04d"), yearReal); - strYearReal2.Printf(_T("%02d"), yearReal % 100); - str.Replace(strYear, replacement3); - str.Replace(strYear2,replacement4); - str.Replace(replacement3, strYearReal); - str.Replace(replacement4, strYearReal2); + // now replace the replacement year with the real year: + // notice that we have to replace the 4 digit year with + // a unique string not appearing in strftime() output + // first to prevent the 2 digit year from matching any + // substring of the 4 digit year (but any day, month, + // hours or minutes components should be safe because + // they are never in 70-99 range) + wxString replacement("|"); + while ( str.find(replacement) != wxString::npos ) + replacement += '|'; - // and replace back all occurrences of replacement string - if ( wasReplaced ) - { - str.Replace(replacement2, strYear2); - str.Replace(replacement, strYear); - } + str.Replace(wxString::Format("%d", year), + replacement); + str.Replace(wxString::Format("%d", year % 100), + wxString::Format("%d", yearReal % 100)); + str.Replace(replacement, + wxString::Format("%d", yearReal)); res += str; }