X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/68379eaf0ae64d105f8244b1db83e793f7dd83b0..414dfb5804fc568b26fec3f8a8ecc2f25addedfd:/src/common/datetime.cpp diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 7828abd182..270d110634 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -536,10 +536,10 @@ wxDateTime::Tm::Tm(const struct tm& tm, const TimeZone& tz) : m_tz(tz) { msec = 0; - sec = tm.tm_sec; - min = tm.tm_min; - hour = tm.tm_hour; - mday = tm.tm_mday; + sec = (wxDateTime::wxDateTime_t)tm.tm_sec; + min = (wxDateTime::wxDateTime_t)tm.tm_min; + hour = (wxDateTime::wxDateTime_t)tm.tm_hour; + mday = (wxDateTime::wxDateTime_t)tm.tm_mday; mon = (wxDateTime::Month)tm.tm_mon; year = 1900 + tm.tm_year; wday = tm.tm_wday; @@ -597,7 +597,7 @@ void wxDateTime::Tm::AddDays(int dayDiff) dayDiff += GetNumOfDaysInMonth(year, mon); } - mday += dayDiff; + mday = (wxDateTime::wxDateTime_t)( mday + dayDiff ); while ( mday > GetNumOfDaysInMonth(year, mon) ) { mday -= GetNumOfDaysInMonth(year, mon); @@ -1646,19 +1646,49 @@ wxDateTime& wxDateTime::Add(const wxDateSpan& diff) // Weekday and monthday stuff // ---------------------------------------------------------------------------- -bool wxDateTime::SetToTheWeek(wxDateTime_t numWeek, - WeekDay weekday, - WeekFlags flags) +// convert Sun, Mon, ..., Sat into 6, 0, ..., 5 +static inline int ConvertWeekDayToMondayBase(int wd) +{ + return wd == wxDateTime::Sun ? 6 : wd - 1; +} + +/* static */ +wxDateTime +wxDateTime::SetToWeekOfYear(int year, wxDateTime_t numWeek, WeekDay wd) { wxASSERT_MSG( numWeek > 0, _T("invalid week number: weeks are counted from 1") ); - int year = GetYear(); + // Jan 4 always lies in the 1st week of the year + wxDateTime dt(4, Jan, year); + dt.SetToWeekDayInSameWeek(wd); + dt += wxDateSpan::Weeks(numWeek - 1); + + return dt; +} +// use a separate function to avoid warnings about using deprecated +// SetToTheWeek in GetWeek below +static wxDateTime +SetToTheWeek(int year, + wxDateTime::wxDateTime_t numWeek, + wxDateTime::WeekDay weekday, + wxDateTime::WeekFlags flags) +{ // Jan 4 always lies in the 1st week of the year - Set(4, Jan, year); - SetToWeekDayInSameWeek(weekday, flags) += wxDateSpan::Weeks(numWeek - 1); + wxDateTime dt(4, wxDateTime::Jan, year); + dt.SetToWeekDayInSameWeek(weekday, flags); + dt += wxDateSpan::Weeks(numWeek - 1); + return dt; +} + +bool wxDateTime::SetToTheWeek(wxDateTime_t numWeek, + WeekDay weekday, + WeekFlags flags) +{ + int year = GetYear(); + *this = ::SetToTheWeek(year, numWeek, weekday, flags); if ( GetYear() != year ) { // oops... numWeek was too big @@ -1668,6 +1698,13 @@ bool wxDateTime::SetToTheWeek(wxDateTime_t numWeek, return true; } +wxDateTime wxDateTime::GetWeek(wxDateTime_t numWeek, + WeekDay weekday, + WeekFlags flags) const +{ + return ::SetToTheWeek(GetYear(), numWeek, weekday, flags); +} + wxDateTime& wxDateTime::SetToLastMonthDay(Month month, int year) { @@ -1833,43 +1870,78 @@ bool wxDateTime::SetToWeekDay(WeekDay weekday, } } -wxDateTime::wxDateTime_t wxDateTime::GetDayOfYear(const TimeZone& tz) const +static inline +wxDateTime::wxDateTime_t GetDayOfYearFromTm(const wxDateTime::Tm& tm) { - Tm tm(GetTm(tz)); + return (wxDateTime::wxDateTime_t)(gs_cumulatedDays[wxDateTime::IsLeapYear(tm.year)][tm.mon] + tm.mday); +} - return gs_cumulatedDays[IsLeapYear(tm.year)][tm.mon] + tm.mday; +wxDateTime::wxDateTime_t wxDateTime::GetDayOfYear(const TimeZone& tz) const +{ + return GetDayOfYearFromTm(GetTm(tz)); } -wxDateTime::wxDateTime_t wxDateTime::GetWeekOfYear(wxDateTime::WeekFlags flags, - const TimeZone& tz) const +wxDateTime::wxDateTime_t +wxDateTime::GetWeekOfYear(wxDateTime::WeekFlags flags, const TimeZone& tz) const { if ( flags == Default_First ) { flags = GetCountry() == USA ? Sunday_First : Monday_First; } - wxDateTime_t nDayInYear = GetDayOfYear(tz); - wxDateTime_t week; + Tm tm(GetTm(tz)); + wxDateTime_t nDayInYear = GetDayOfYearFromTm(tm); - WeekDay wd = GetWeekDay(tz); + int wdTarget = GetWeekDay(tz); + int wdYearStart = wxDateTime(1, Jan, GetYear()).GetWeekDay(); + int week; if ( flags == Sunday_First ) { - week = (nDayInYear - wd + 7) / 7; + // FIXME: First week is not calculated correctly. + week = (nDayInYear - wdTarget + 7) / 7; + if ( wdYearStart == Wed || wdYearStart == Thu ) + week++; } - else + else // week starts with monday { - // have to shift the week days values - week = (nDayInYear - (wd - 1 + 7) % 7 + 7) / 7; - } + // adjust the weekdays to non-US style. + wdYearStart = ConvertWeekDayToMondayBase(wdYearStart); + wdTarget = ConvertWeekDayToMondayBase(wdTarget); - // FIXME some more elegant way?? - WeekDay wdYearStart = wxDateTime(1, Jan, GetYear()).GetWeekDay(); - if ( wdYearStart == Wed || wdYearStart == Thu ) - { - week++; + // quoting from http://www.cl.cam.ac.uk/~mgk25/iso-time.html: + // + // Week 01 of a year is per definition the first week that has the + // Thursday in this year, which is equivalent to the week that + // contains the fourth day of January. In other words, the first + // week of a new year is the week that has the majority of its + // days in the new year. Week 01 might also contain days from the + // previous year and the week before week 01 of a year is the last + // week (52 or 53) of the previous year even if it contains days + // from the new year. A week starts with Monday (day 1) and ends + // with Sunday (day 7). + // + + // 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; + + // be careful to check for overflow in the next year + if ( week == 53 && tm.mday - wdTarget > 28 ) + week = 1; + } + else // Jan 1 is in the last week of the previous year + { + // 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; + } } - return week; + return (wxDateTime::wxDateTime_t)week; } wxDateTime::wxDateTime_t wxDateTime::GetWeekOfMonth(wxDateTime::WeekFlags flags, @@ -1902,7 +1974,7 @@ wxDateTime& wxDateTime::SetToYearDay(wxDateTime::wxDateTime_t yday) // yday lies in December then if ( (mon == Dec) || (yday <= gs_cumulatedDays[isLeap][mon + 1]) ) { - Set(yday - gs_cumulatedDays[isLeap][mon], mon, year); + Set((wxDateTime::wxDateTime_t)(yday - gs_cumulatedDays[isLeap][mon]), mon, year); break; } @@ -2395,11 +2467,11 @@ const wxChar *wxDateTime::ParseRfc822Date(const wxChar* date) return (wxChar *)NULL; } - wxDateTime_t day = *p++ - _T('0'); + wxDateTime_t day = (wxDateTime_t)(*p++ - _T('0')); if ( wxIsdigit(*p) ) { day *= 10; - day += *p++ - _T('0'); + day = (wxDateTime_t)(day + (*p++ - _T('0'))); } if ( *p++ != _T(' ') ) @@ -2493,7 +2565,7 @@ const wxChar *wxDateTime::ParseRfc822Date(const wxChar* date) return (wxChar *)NULL; } - wxDateTime_t hour = *p++ - _T('0'); + wxDateTime_t hour = (wxDateTime_t)(*p++ - _T('0')); if ( !wxIsdigit(*p) ) { @@ -2501,7 +2573,7 @@ const wxChar *wxDateTime::ParseRfc822Date(const wxChar* date) } hour *= 10; - hour += *p++ - _T('0'); + hour = (wxDateTime_t)(hour + (*p++ - _T('0'))); if ( *p++ != _T(':') ) { @@ -2513,7 +2585,7 @@ const wxChar *wxDateTime::ParseRfc822Date(const wxChar* date) return (wxChar *)NULL; } - wxDateTime_t min = *p++ - _T('0'); + wxDateTime_t min = (wxDateTime_t)(*p++ - _T('0')); if ( !wxIsdigit(*p) ) { @@ -2521,7 +2593,7 @@ const wxChar *wxDateTime::ParseRfc822Date(const wxChar* date) } min *= 10; - min += *p++ - _T('0'); + min = (wxDateTime_t)(min + *p++ - _T('0')); wxDateTime_t sec = 0; if ( *p++ == _T(':') ) @@ -2531,7 +2603,7 @@ const wxChar *wxDateTime::ParseRfc822Date(const wxChar* date) return (wxChar *)NULL; } - sec = *p++ - _T('0'); + sec = (wxDateTime_t)(*p++ - _T('0')); if ( !wxIsdigit(*p) ) { @@ -2539,7 +2611,7 @@ const wxChar *wxDateTime::ParseRfc822Date(const wxChar* date) } sec *= 10; - sec += *p++ - _T('0'); + sec = (wxDateTime_t)(sec + *p++ - _T('0')); } if ( *p++ != _T(' ') ) @@ -3320,19 +3392,23 @@ const wxChar *wxDateTime::ParseDate(const wxChar *date) { wxString date = wxGetTranslation(literalDates[n].str); size_t len = date.length(); - if ( wxStrlen(p) >= len && (wxString(p, len).CmpNoCase(date) == 0) ) + if ( wxStrlen(p) >= len ) { - // nothing can follow this, so stop here - p += len; - - int dayDiffFromToday = literalDates[n].dayDiffFromToday; - *this = Today(); - if ( dayDiffFromToday ) + wxString str(p, len); + if ( str.CmpNoCase(date) == 0 ) { - *this += wxDateSpan::Days(dayDiffFromToday); - } + // nothing can follow this, so stop here + p += len; + + int dayDiffFromToday = literalDates[n].dayDiffFromToday; + *this = Today(); + if ( dayDiffFromToday ) + { + *this += wxDateSpan::Days(dayDiffFromToday); + } - return p; + return p; + } } } @@ -3387,9 +3463,11 @@ const wxChar *wxDateTime::ParseDate(const wxChar *date) } else // may be either day or year { - wxDateTime_t maxDays = haveMon + wxDateTime_t maxDays = (wxDateTime_t)( + haveMon ? GetNumOfDaysInMonth(haveYear ? year : Inv_Year, mon) - : 31; + : 31 + ); // can it be day? if ( (val == 0) || (val > (unsigned long)maxDays) ) @@ -3443,7 +3521,7 @@ const wxChar *wxDateTime::ParseDate(const wxChar *date) { // no need to check in month range as always < 12, but // the days are counted from 1 unlike the months - day = (wxDateTime_t)mon + 1; + day = (wxDateTime_t)(mon + 1); haveDay = true; } else @@ -3565,7 +3643,7 @@ const wxChar *wxDateTime::ParseDate(const wxChar *date) // we're in the current year then if ( (year > 0) && (year <= (int)GetNumOfDaysInMonth(Inv_Year, mon)) ) { - day = year; + day = (wxDateTime_t)year; haveMon = true; haveYear = false; @@ -3954,7 +4032,7 @@ void wxDateTimeHolidayAuthority::AddAuthority(wxDateTimeHolidayAuthority *auth) wxDateTimeHolidayAuthority::~wxDateTimeHolidayAuthority() { - // nothing to do here + // required here for Darwin } // ----------------------------------------------------------------------------