X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/df5168c427b51f1ab2b3200a5c8f7626b3d24aae..532c773634cccf5c19f42aac5d2425ed3e7bb12a:/src/common/datetime.cpp diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 6751dd2ad9..ce2814825e 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -52,7 +52,7 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "datetime.h" #endif @@ -78,10 +78,27 @@ #include #include "wx/datetime.h" -#include "wx/timer.h" // for wxGetLocalTimeMillis() +#include "wx/stopwatch.h" // for wxGetLocalTimeMillis() const long wxDateTime::TIME_T_FACTOR = 1000l; +#if wxUSE_EXTENDED_RTTI + +template<> void wxStringReadValue(const wxString &s , wxDateTime &data ) +{ + data.ParseFormat(s,wxT("%Y-%m-%d %H:%M:%S")) ; +} + +template<> void wxStringWriteValue(wxString &s , const wxDateTime &data ) +{ + s = data.Format(wxT("%Y-%m-%d %H:%M:%S")) ; +} + +wxCUSTOM_TYPE_INFO(wxDateTime, wxToStringConverter , wxFromStringConverter) + +#endif + +// // ---------------------------------------------------------------------------- // conditional compilation // ---------------------------------------------------------------------------- @@ -222,16 +239,6 @@ const wxDateTime wxDefaultDateTime; wxDateTime::Country wxDateTime::ms_country = wxDateTime::Country_Unknown; -// ---------------------------------------------------------------------------- -// private globals -// ---------------------------------------------------------------------------- - -// a critical section is needed to protect GetTimeZone() static -// variable in MT case -#if wxUSE_THREADS - static wxCriticalSection gs_critsectTimezone; -#endif // wxUSE_THREADS - // ---------------------------------------------------------------------------- // private functions // ---------------------------------------------------------------------------- @@ -267,13 +274,10 @@ wxDateTime::wxDateTime_t GetNumOfDaysInMonth(int year, wxDateTime::Month month) // (in seconds) static int GetTimeZone() { +#ifdef WX_GMTOFF_IN_TM // set to TRUE when the timezone is set static bool s_timezoneSet = FALSE; -#ifdef WX_GMTOFF_IN_TM static long gmtoffset = LONG_MAX; // invalid timezone -#endif - - wxCRIT_SECT_LOCKER(lock, gs_critsectTimezone); // ensure that the timezone variable is set by calling localtime if ( !s_timezoneSet ) @@ -286,19 +290,16 @@ static int GetTimeZone() tm = localtime(&t); s_timezoneSet = TRUE; -#ifdef WX_GMTOFF_IN_TM // note that GMT offset is the opposite of time zone and so to return // consistent results in both WX_GMTOFF_IN_TM and !WX_GMTOFF_IN_TM // cases we have to negate it gmtoffset = -tm->tm_gmtoff; -#endif } -#ifdef WX_GMTOFF_IN_TM return (int)gmtoffset; -#else +#else // !WX_GMTOFF_IN_TM return (int)WX_TIMEZONE; -#endif +#endif // WX_GMTOFF_IN_TM/!WX_GMTOFF_IN_TM } // return the integral part of the JDN for the midnight of the given date (to @@ -356,6 +357,12 @@ static wxString CallStrftime(const wxChar *format, const tm* tm) #ifdef HAVE_STRPTIME +// glibc2 doesn't define this in the headers unless _XOPEN_SOURCE is defined +// which, unfortunately, wreaks havoc elsewhere +#if defined(__GLIBC__) && (__GLIBC__ == 2) + extern "C" char *strptime(const char *, const char *, struct tm *); +#endif + // Unicode-friendly strptime() wrapper static const wxChar * CallStrptime(const wxChar *input, const char *fmt, tm *tm) @@ -2680,7 +2687,7 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date, // parse the optional width size_t width = 0; - while ( isdigit(*++fmt) ) + while ( wxIsdigit(*++fmt) ) { width *= 10; width += *fmt - _T('0'); @@ -3195,6 +3202,14 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date, Set(tm); + // finally check that the week day is consistent -- if we had it + if ( haveWDay && GetWeekDay() != wday ) + { + wxLogDebug(_T("inconsistsnet week day in wxDateTime::ParseFormat()")); + + return NULL; + } + return input; } @@ -3202,11 +3217,48 @@ const wxChar *wxDateTime::ParseDateTime(const wxChar *date) { wxCHECK_MSG( date, (wxChar *)NULL, _T("NULL pointer in wxDateTime::Parse") ); - // there is a public domain version of getdate.y, but it only works for - // English... - wxFAIL_MSG(_T("TODO")); + // Set to current day and hour, so strings like '14:00' becomes today at + // 14, not some other random date + wxDateTime dtDate = wxDateTime::Today(); + wxDateTime dtTime = wxDateTime::Today(); + + const wxChar* pchTime; + + // Try to parse the beginning of the string as a date + const wxChar* pchDate = dtDate.ParseDate(date); + + // We got a date in the beginning, see if there is a time specified after the date + if ( pchDate ) + { + // Skip spaces, as the ParseTime() function fails on spaces + while ( wxIsspace(*pchDate) ) + pchDate++; + + pchTime = dtTime.ParseTime(pchDate); + } + else // no date in the beginning + { + // check and see if we have a time followed by a date + pchTime = dtTime.ParseTime(date); + if ( pchTime ) + { + while ( wxIsspace(*pchTime) ) + pchTime++; + + pchDate = dtDate.ParseDate(pchTime); + } + } + + // If we have a date specified, set our own data to the same date + if ( !pchDate || !pchTime ) + return NULL; + + Set(dtDate.GetDay(), dtDate.GetMonth(), dtDate.GetYear(), + dtTime.GetHour(), dtTime.GetMinute(), dtTime.GetSecond(), + dtTime.GetMillisecond()); - return (wxChar *)NULL; + // Return endpoint of scan + return pchDate > pchTime ? pchDate : pchTime; } const wxChar *wxDateTime::ParseDate(const wxChar *date) @@ -3471,8 +3523,7 @@ const wxChar *wxDateTime::ParseDate(const wxChar *date) mon = (wxDateTime::Month)(day - 1); // we're in the current year then - if ( (year > 0) && - (unsigned)year <= GetNumOfDaysInMonth(Inv_Year, mon) ) + if ( (year > 0) && (year <= (int)GetNumOfDaysInMonth(Inv_Year, mon)) ) { day = year;