X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4ded51f2fa07a060f5212a8957db5ce356775866..c2a331e02732bb6a04a42ebf646d54b4373ad122:/src/common/datetime.cpp diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 7ff53bacf5..19236b62d8 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 @@ -75,12 +75,10 @@ #include "wx/tokenzr.h" #include "wx/module.h" -#define wxDEFINE_TIME_CONSTANTS // before including datetime.h - #include #include "wx/datetime.h" -#include "wx/timer.h" // for wxGetLocalTimeMillis() +#include "wx/stopwatch.h" // for wxGetLocalTimeMillis() const long wxDateTime::TIME_T_FACTOR = 1000l; @@ -88,7 +86,8 @@ const long wxDateTime::TIME_T_FACTOR = 1000l; // conditional compilation // ---------------------------------------------------------------------------- -#if defined(HAVE_STRPTIME) && defined(__LINUX__) +#if defined(HAVE_STRPTIME) && defined(__GLIBC__) && \ + ((__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0)) // glibc 2.0.7 strptime() is broken - the following snippet causes it to // crash (instead of just failing): // @@ -161,7 +160,7 @@ public: virtual void OnExit() { wxDateTimeHolidayAuthority::ClearAllAuthorities(); - wxDateTimeHolidayAuthority::ms_authorities.Clear(); + wxDateTimeHolidayAuthority::ms_authorities.clear(); } private: @@ -223,16 +222,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 // ---------------------------------------------------------------------------- @@ -268,13 +257,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 ) @@ -287,19 +273,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 @@ -342,7 +325,7 @@ static long GetTruncatedJDN(wxDateTime::wxDateTime_t day, - JDN_OFFSET; } -// this function is a wrapper around strftime(3) +// this function is a wrapper around strftime(3) adding error checking static wxString CallStrftime(const wxChar *format, const tm* tm) { wxChar buf[4096]; @@ -355,6 +338,41 @@ static wxString CallStrftime(const wxChar *format, const tm* tm) return wxString(buf); } +#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) +{ + // the problem here is that strptime() returns pointer into the string we + // passed to it while we're really interested in the pointer into the + // original, Unicode, string so we try to transform the pointer back +#if wxUSE_UNICODE + wxCharBuffer inputMB(wxConvertWX2MB(input)); +#else // ASCII + const char * const inputMB = input; +#endif // Unicode/Ascii + + const char *result = strptime(inputMB, fmt, tm); + if ( !result ) + return NULL; + +#if wxUSE_UNICODE + // FIXME: this is wrong in presence of surrogates &c + return input + (result - inputMB.data()); +#else // ASCII + return result; +#endif // Unicode/Ascii +} + +#endif // HAVE_STRPTIME + // if year and/or month have invalid values, replace them with the current ones static void ReplaceDefaultYearMonthWithCurrent(int *year, wxDateTime::Month *month) @@ -2652,7 +2670,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'); @@ -2921,12 +2939,13 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date, case _T('x'): // locale default date representation #ifdef HAVE_STRPTIME - // try using strptime() - it may fail even if the input is + // try using strptime() -- it may fail even if the input is // correct but the date is out of range, so we will fall back - // to our generic code anyhow (FIXME !Unicode friendly) + // to our generic code anyhow { struct tm tm; - const wxChar *result = strptime(input, "%x", &tm); + + const wxChar *result = CallStrptime(input, "%x", &tm); if ( result ) { input = result; @@ -2991,7 +3010,7 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date, { // use strptime() to do it for us (FIXME !Unicode friendly) struct tm tm; - input = strptime(input, "%X", &tm); + input = CallStrptime(input, "%X", &tm); if ( !input ) { return (wxChar *)NULL; @@ -3166,6 +3185,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; } @@ -3785,7 +3812,7 @@ wxHolidayAuthoritiesArray wxDateTimeHolidayAuthority::ms_authorities; /* static */ bool wxDateTimeHolidayAuthority::IsHoliday(const wxDateTime& dt) { - size_t count = ms_authorities.GetCount(); + size_t count = ms_authorities.size(); for ( size_t n = 0; n < count; n++ ) { if ( ms_authorities[n]->DoIsHoliday(dt) ) @@ -3805,9 +3832,9 @@ wxDateTimeHolidayAuthority::GetHolidaysInRange(const wxDateTime& dtStart, { wxDateTimeArray hol; - holidays.Empty(); + holidays.Clear(); - size_t count = ms_authorities.GetCount(); + size_t count = ms_authorities.size(); for ( size_t nAuth = 0; nAuth < count; nAuth++ ) { ms_authorities[nAuth]->DoGetHolidaysInRange(dtStart, dtEnd, hol); @@ -3817,7 +3844,7 @@ wxDateTimeHolidayAuthority::GetHolidaysInRange(const wxDateTime& dtStart, holidays.Sort(wxDateTimeCompareFunc); - return holidays.GetCount(); + return holidays.size(); } /* static */ @@ -3829,7 +3856,12 @@ void wxDateTimeHolidayAuthority::ClearAllAuthorities() /* static */ void wxDateTimeHolidayAuthority::AddAuthority(wxDateTimeHolidayAuthority *auth) { - ms_authorities.Add(auth); + ms_authorities.push_back(auth); +} + +wxDateTimeHolidayAuthority::~wxDateTimeHolidayAuthority() +{ + // nothing to do here } // ----------------------------------------------------------------------------