X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/cf44a61c2410fab7cc9b71c5f2578296e44c28e7..3e822cd8d0bdf04cd2c7a3dddff61dcc211f7439:/src/common/datetime.cpp diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 12732e144b..917e40d3a0 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -169,7 +169,7 @@ wxCUSTOM_TYPE_INFO(wxDateTime, wxToStringConverter , wxFromStringCon #endif #endif // !WX_TIMEZONE && !WX_GMTOFF_IN_TM -#if wxUSE_THREADS +#if (!defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)) && wxUSE_THREADS && !defined(__WINDOWS__) static wxMutex timeLock; #endif @@ -179,7 +179,7 @@ struct tm *wxLocaltime_r(const time_t* ticks, struct tm* temp) #if wxUSE_THREADS && !defined(__WINDOWS__) // No need to waste time with a mutex on windows since it's using // thread local storage for localtime anyway. - wxMutexLocker(timeLock); + wxMutexLocker locker(timeLock); #endif memcpy(temp, localtime(ticks), sizeof(struct tm)); return temp; @@ -192,7 +192,7 @@ struct tm *wxGmtime_r(const time_t* ticks, struct tm* temp) #if wxUSE_THREADS && !defined(__WINDOWS__) // No need to waste time with a mutex on windows since it's // using thread local storage for gmtime anyway. - wxMutexLocker(timeLock); + wxMutexLocker locker(timeLock); #endif memcpy(temp, gmtime(ticks), sizeof(struct tm)); return temp; @@ -2407,34 +2407,40 @@ wxString wxDateTime::Format(const wxChar *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, _T("logic error in wxDateTime::Format") ); - wxString strYear, strYear2; + wxString strYear, strYear2; strYear.Printf(_T("%d"), year); strYear2.Printf(_T("%d"), year % 100); - - // find two strings not occurring in format (this is surely + + // find four strings not occurring in format (this is surely // not the optimal way of doing it... improvements welcome!) wxString fmt2 = format; - wxString replacement = (wxChar)-1; - while ( fmt2.Find(replacement) != wxNOT_FOUND ) - { - replacement << (wxChar)-1; - } - - wxString replacement2 = (wxChar)-2; - while ( fmt2.Find(replacement) != wxNOT_FOUND ) - { - replacement << (wxChar)-2; - } - + 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; - if ( !wasReplaced ) - wasReplaced = fmt2.Replace(strYear2, replacement2) > 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 @@ -2459,11 +2465,17 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const &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, strYearReal); - str.Replace(strYear2, strYearReal2); + str.Replace(strYear, replacement3); + str.Replace(strYear2,replacement4); + str.Replace(replacement3, strYearReal); + str.Replace(replacement4, strYearReal2); // and replace back all occurrences of replacement string if ( wasReplaced )