fixed GetWeekOfYear() for first/last week in some cases (patch 908793)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@29100 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2004-09-11 21:37:28 +00:00
parent 9d769508fb
commit 1c5d27e2ab
2 changed files with 63 additions and 19 deletions

View File

@ -1833,41 +1833,82 @@ 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 gs_cumulatedDays[IsLeapYear(tm.year)][tm.mon] + tm.mday;
return gs_cumulatedDays[wxDateTime::IsLeapYear(tm.year)][tm.mon] + tm.mday;
}
wxDateTime::wxDateTime_t wxDateTime::GetWeekOfYear(wxDateTime::WeekFlags flags,
const TimeZone& tz) const
wxDateTime::wxDateTime_t wxDateTime::GetDayOfYear(const TimeZone& tz) const
{
return GetDayOfYearFromTm(GetTm(tz));
}
// convert Sun, Mon, ..., Sat into 6, 0, ..., 5
static inline int ConvertWeekDayToMondayBase(int wd)
{
return wd == wxDateTime::Sun ? 6 : wd - 1;
}
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;
}
else
{
// have to shift the week days values
week = (nDayInYear - (wd - 1 + 7) % 7 + 7) / 7;
}
// FIXME some more elegant way??
WeekDay wdYearStart = wxDateTime(1, Jan, GetYear()).GetWeekDay();
// FIXME: First week is not calculated correctly.
week = (nDayInYear - wdTarget + 7) / 7;
if ( wdYearStart == Wed || wdYearStart == Thu )
{
week++;
}
else // week starts with monday
{
// 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:
//
// 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;
}

View File

@ -323,6 +323,7 @@ for n in range(20):
{ { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
{ { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
{ { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
};
wxDateTime dt;
@ -425,6 +426,8 @@ for n in range(20):
{ { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
{ { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
{ { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 },
{ { 30, wxDateTime::Dec, 2003 }, 1, 5, 5, 364 },
{ { 2, wxDateTime::Jan, 2004 }, 1, 1, 1, 2 },
};
for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )