X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/59068d79f7fcc94d320cf41ce1ed7f0a8851b125..0f5378d414cb68caaa535199c1af12dec1720c3d:/src/common/datetime.cpp?ds=sidebyside diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 066ac07047..6ea7a0a37a 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -63,7 +63,7 @@ #if !defined(wxUSE_DATETIME) || wxUSE_DATETIME #ifndef WX_PRECOMP - #ifdef __WXMSW__ + #ifdef __WINDOWS__ #include "wx/msw/wrapwin.h" #endif #include "wx/string.h" @@ -109,90 +109,6 @@ wxCUSTOM_TYPE_INFO(wxDateTime, wxToStringConverter , wxFromStringCon #endif // wxUSE_EXTENDED_RTTI - -// ---------------------------------------------------------------------------- -// conditional compilation -// ---------------------------------------------------------------------------- - -#if defined(__MWERKS__) && wxUSE_UNICODE - #include -#endif - -#if defined(__DJGPP__) || defined(__WINE__) - #include - #include -#endif - -// 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 // ---------------------------------------------------------------------------- @@ -1186,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 @@ -1686,6 +1602,56 @@ wxDateTime& wxDateTime::Add(const wxDateSpan& diff) return *this; } +wxDateSpan wxDateTime::DiffAsDateSpan(const wxDateTime& dt) const +{ + wxASSERT_MSG( IsValid() && dt.IsValid(), wxT("invalid wxDateTime")); + + // If dt is larger than this, calculations below needs to be inverted. + int inv = 1; + if ( dt > *this ) + inv = -1; + + int y = GetYear() - dt.GetYear(); + int m = GetMonth() - dt.GetMonth(); + int d = GetDay() - dt.GetDay(); + + // If month diff is negative, dt is the year before, so decrease year + // and set month diff to its inverse, e.g. January - December should be 1, + // not -11. + if ( m * inv < 0 || (m == 0 && d * inv < 0)) + { + m += inv * MONTHS_IN_YEAR; + y -= inv; + } + + // Same logic for days as for months above. + if ( d * inv < 0 ) + { + // Use number of days in month from the month which end date we're + // crossing. That is month before this for positive diff, and this + // month for negative diff. + // If we're on january and using previous month, we get december + // previous year, but don't care, december has same amount of days + // every year. + wxDateTime::Month monthfordays = GetMonth(); + if (inv > 0 && monthfordays == wxDateTime::Jan) + monthfordays = wxDateTime::Dec; + else if (inv > 0) + monthfordays = static_cast(monthfordays - 1); + + d += inv * wxDateTime::GetNumberOfDays(monthfordays, GetYear()); + m -= inv; + } + + int w = d / DAYS_PER_WEEK; + + // Remove weeks from d, since wxDateSpan only keep days as the ones + // not in complete weeks + d -= w * DAYS_PER_WEEK; + + return wxDateSpan(y, m, w, d); +} + // ---------------------------------------------------------------------------- // Weekday and monthday stuff // ---------------------------------------------------------------------------- @@ -1955,7 +1921,6 @@ wxDateTime::GetWeekOfYear(wxDateTime::WeekFlags flags, const TimeZone& tz) const { // adjust the weekdays to non-US style. wdYearStart = ConvertWeekDayToMondayBase(wdYearStart); - wdTarget = ConvertWeekDayToMondayBase(wdTarget); // quoting from http://www.cl.cam.ac.uk/~mgk25/iso-time.html: // @@ -1971,22 +1936,24 @@ wxDateTime::GetWeekOfYear(wxDateTime::WeekFlags flags, const TimeZone& tz) const // // if Jan 1 is Thursday or less, it is in the first week of this year - if ( wdYearStart < 4 ) - { - // count the number of entire weeks between Jan 1 and this date - week = (nDayInYear + wdYearStart + 6 - wdTarget)/7; + int dayCountFix = wdYearStart < 4 ? 6 : -1; - // be careful to check for overflow in the next year - if ( week == 53 && tm.mday - wdTarget > 28 ) - week = 1; + // count the number of week + week = (nDayInYear + wdYearStart + dayCountFix) / DAYS_PER_WEEK; + + // check if we happen to be at the last week of previous year: + if ( week == 0 ) + { + week = wxDateTime(31, Dec, GetYear() - 1).GetWeekOfYear(); } - else // Jan 1 is in the last week of the previous year + else if ( week == 53 ) { - // check if we happen to be at the last week of previous year: - if ( tm.mon == Jan && tm.mday < 8 - wdYearStart ) - week = wxDateTime(31, Dec, GetYear()-1).GetWeekOfYear(); - else - week = (nDayInYear + wdYearStart - 1 - wdTarget)/7; + int wdYearEnd = (wdYearStart + 364 + IsLeapYear(GetYear())) + % DAYS_PER_WEEK; + + // Week 53 only if last day of year is Thursday or later. + if ( wdYearEnd < 3 ) + week = 1; } } @@ -2282,7 +2249,7 @@ WXDLLIMPEXP_BASE void wxPrevWDay(wxDateTime::WeekDay& wd) : (wxDateTime::WeekDay)(wd - 1); } -#ifdef __WXMSW__ +#ifdef __WINDOWS__ wxDateTime& wxDateTime::SetFromMSWSysTime(const SYSTEMTIME& st) { @@ -2330,6 +2297,6 @@ void wxDateTime::GetAsMSWSysDate(SYSTEMTIME* st) const st->wMilliseconds = 0; } -#endif // __WXMSW__ +#endif // __WINDOWS__ #endif // wxUSE_DATETIME