X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7e9c57542f80717be57dfb1ea51b050c902ebfa2..41fec01fa9e009d84fe353aa494725328d850af1:/src/common/datetime.cpp diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 4bbca2e476..b70f3331fb 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -75,6 +75,7 @@ #endif // WX_PRECOMP #include "wx/thread.h" +#include "wx/time.h" #include "wx/tokenzr.h" #include @@ -108,126 +109,6 @@ wxCUSTOM_TYPE_INFO(wxDateTime, wxToStringConverter , wxFromStringCon #endif // wxUSE_EXTENDED_RTTI - -// ---------------------------------------------------------------------------- -// conditional compilation -// ---------------------------------------------------------------------------- - -#if defined(__MWERKS__) && wxUSE_UNICODE - #include -#endif - -#if !defined(WX_TIMEZONE) && !defined(WX_GMTOFF_IN_TM) - #if defined(__WXPALMOS__) - #define WX_GMTOFF_IN_TM - #elif defined(__BORLANDC__) || defined(__MINGW32__) || defined(__VISAGECPP__) - #define WX_TIMEZONE _timezone - #elif defined(__MWERKS__) - long wxmw_timezone = 28800; - #define WX_TIMEZONE wxmw_timezone - #elif defined(__DJGPP__) || defined(__WINE__) - #include - #include - static long wxGetTimeZone() - { - struct timeb tb; - ftime(&tb); - return tb.timezone; - } - #define WX_TIMEZONE wxGetTimeZone() - #elif defined(__DARWIN__) - #define WX_GMTOFF_IN_TM - #elif wxCHECK_VISUALC_VERSION(8) - // While _timezone is still present in (some versions of) VC CRT, it's - // deprecated and _get_timezone() should be used instead. - static long wxGetTimeZone() - { - // The type of _get_timezone() parameter seems to have changed - // between VC8 and VC9. - #ifdef __VISUALC8__ - int t; - #else - long t; - #endif - _get_timezone(&t); - return t; - } - #define WX_TIMEZONE wxGetTimeZone() - #else // unknown platform - try timezone - #define WX_TIMEZONE timezone - #endif -#endif // !WX_TIMEZONE && !WX_GMTOFF_IN_TM - -// NB: VC8 safe time functions could/should be used for wxMSW as well probably -#if defined(__WXWINCE__) && defined(__VISUALC8__) - -struct tm *wxLocaltime_r(const time_t *t, struct tm* tm) -{ - __time64_t t64 = *t; - return _localtime64_s(tm, &t64) == 0 ? tm : NULL; -} - -struct tm *wxGmtime_r(const time_t* t, struct tm* tm) -{ - __time64_t t64 = *t; - return _gmtime64_s(tm, &t64) == 0 ? tm : NULL; -} - -#else // !wxWinCE with VC8 - -#if (!defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)) && wxUSE_THREADS && !defined(__WINDOWS__) -static wxMutex timeLock; -#endif - -#ifndef HAVE_LOCALTIME_R -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 locker(timeLock); -#endif - - // Borland CRT crashes when passed 0 ticks for some reason, see SF bug 1704438 -#ifdef __BORLANDC__ - if ( !*ticks ) - return NULL; -#endif - - const tm * const t = localtime(ticks); - if ( !t ) - return NULL; - - memcpy(temp, t, sizeof(struct tm)); - return temp; -} -#endif // !HAVE_LOCALTIME_R - -#ifndef HAVE_GMTIME_R -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 locker(timeLock); -#endif - -#ifdef __BORLANDC__ - if ( !*ticks ) - return NULL; -#endif - - const tm * const t = gmtime(ticks); - if ( !t ) - return NULL; - - memcpy(temp, gmtime(ticks), sizeof(struct tm)); - return temp; -} -#endif // !HAVE_GMTIME_R - -#endif // wxWinCE with VC8/other platforms - // ---------------------------------------------------------------------------- // macros // ---------------------------------------------------------------------------- @@ -355,38 +236,6 @@ wxDateTime::wxDateTime_t GetNumOfDaysInMonth(int year, wxDateTime::Month month) return daysInMonth[wxDateTime::IsLeapYear(year)][month]; } -// returns the time zone in the C sense, i.e. the difference UTC - local -// (in seconds) -// NOTE: not static because used by datetimefmt.cpp -int GetTimeZone() -{ -#ifdef WX_GMTOFF_IN_TM - // set to true when the timezone is set - static bool s_timezoneSet = false; - static long gmtoffset = LONG_MAX; // invalid timezone - - // ensure that the timezone variable is set by calling wxLocaltime_r - if ( !s_timezoneSet ) - { - // just call wxLocaltime_r() instead of figuring out whether this - // system supports tzset(), _tzset() or something else - time_t t = 0; - struct tm tm; - - wxLocaltime_r(&t, &tm); - s_timezoneSet = true; - - // 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; - } - return (int)gmtoffset; -#else // !WX_GMTOFF_IN_TM - return WX_TIMEZONE; -#endif // WX_GMTOFF_IN_TM/!WX_GMTOFF_IN_TM -} - // return the integral part of the JDN for the midnight of the given date (to // get the real JDN you need to add 0.5, this is, in fact, JDN of the // noon of the previous day) @@ -440,8 +289,15 @@ wxString CallStrftime(const wxString& format, const tm* tm) if ( !wxStrftime(buf, WXSIZEOF(buf), format, tm) ) { - // if the format is valid, buffer must be too small? - wxFAIL_MSG(wxT("strftime() failed")); + // There is one special case in which strftime() can return 0 without + // indicating an error: "%p" may give empty string depending on the + // locale, so check for it explicitly. Apparently it's really the only + // exception. + if ( format != wxS("%p") ) + { + // if the format is valid, buffer must be too small? + wxFAIL_MSG(wxT("strftime() failed")); + } buf[0] = '\0'; } @@ -525,9 +381,17 @@ wxDateTime::Tm::Tm(const struct tm& tm, const TimeZone& tz) bool wxDateTime::Tm::IsValid() const { + if ( mon == wxDateTime::Inv_Month ) + return false; + + // We need to check this here to avoid crashing in GetNumOfDaysInMonth() if + // somebody passed us "(wxDateTime::Month)1000". + wxCHECK_MSG( mon >= wxDateTime::Jan && mon < wxDateTime::Inv_Month, false, + wxS("Invalid month value") ); + // we allow for the leap seconds, although we don't use them (yet) return (year != wxDateTime::Inv_Year) && (mon != wxDateTime::Inv_Month) && - (mday <= GetNumOfDaysInMonth(year, mon)) && + (mday > 0 && mday <= GetNumOfDaysInMonth(year, mon)) && (hour < 24) && (min < 60) && (sec < 62) && (msec < 1000); } @@ -597,7 +461,7 @@ wxDateTime::TimeZone::TimeZone(wxDateTime::TZ tz) case wxDateTime::Local: // get the offset from C RTL: it returns the difference GMT-local // while we want to have the offset _from_ GMT, hence the '-' - m_offset = -GetTimeZone(); + m_offset = -wxGetTimeZone(); break; case wxDateTime::GMT_12: @@ -1238,7 +1102,7 @@ wxDateTime wxDateTime::GetEndDST(int year, Country country) // return the current time with ms precision /* static */ wxDateTime wxDateTime::UNow() { - return wxDateTime(wxGetLocalTimeMillis()); + return wxDateTime(wxGetUTCTimeMillis()); } // the values in the tm structure contain the local time @@ -1254,7 +1118,7 @@ wxDateTime& wxDateTime::Set(const struct tm& tm) if ( tm2.tm_year == 70 && tm2.tm_mon == 0 && tm2.tm_mday == 1 ) { return Set((time_t)( - GetTimeZone() + + wxGetTimeZone() + tm2.tm_hour * MIN_PER_HOUR * SEC_PER_MIN + tm2.tm_min * SEC_PER_MIN + tm2.tm_sec)); @@ -1368,7 +1232,7 @@ wxDateTime& wxDateTime::Set(wxDateTime_t day, m_time *= SECONDS_PER_DAY * TIME_T_FACTOR; // JDN corresponds to GMT, we take localtime - Add(wxTimeSpan(hour, minute, second + GetTimeZone(), millisec)); + Add(wxTimeSpan(hour, minute, second + wxGetTimeZone(), millisec)); } return *this; @@ -1507,7 +1371,7 @@ wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const // use C RTL functions struct tm tmstruct; tm *tm; - if ( tz.GetOffset() == -GetTimeZone() ) + if ( tz.GetOffset() == -wxGetTimeZone() ) { // we are working with local time tm = wxLocaltime_r(&time, &tmstruct); @@ -2141,7 +2005,7 @@ int wxDateTime::IsDST(wxDateTime::Country country) const wxDateTime& wxDateTime::MakeTimezone(const TimeZone& tz, bool noDST) { - long secDiff = GetTimeZone() + tz.GetOffset(); + long secDiff = wxGetTimeZone() + tz.GetOffset(); // we need to know whether DST is or not in effect for this date unless // the test disabled by the caller @@ -2156,7 +2020,7 @@ wxDateTime& wxDateTime::MakeTimezone(const TimeZone& tz, bool noDST) wxDateTime& wxDateTime::MakeFromTimezone(const TimeZone& tz, bool noDST) { - long secDiff = GetTimeZone() + tz.GetOffset(); + long secDiff = wxGetTimeZone() + tz.GetOffset(); // we need to know whether DST is or not in effect for this date unless // the test disabled by the caller