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:
@@ -1833,40 +1833,81 @@ 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[wxDateTime::IsLeapYear(tm.year)][tm.mon] + tm.mday;
|
||||||
|
|
||||||
return gs_cumulatedDays[IsLeapYear(tm.year)][tm.mon] + tm.mday;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxDateTime::wxDateTime_t wxDateTime::GetWeekOfYear(wxDateTime::WeekFlags flags,
|
wxDateTime::wxDateTime_t wxDateTime::GetDayOfYear(const TimeZone& tz) const
|
||||||
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 )
|
if ( flags == Default_First )
|
||||||
{
|
{
|
||||||
flags = GetCountry() == USA ? Sunday_First : Monday_First;
|
flags = GetCountry() == USA ? Sunday_First : Monday_First;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxDateTime_t nDayInYear = GetDayOfYear(tz);
|
Tm tm(GetTm(tz));
|
||||||
wxDateTime_t week;
|
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 )
|
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
|
// adjust the weekdays to non-US style.
|
||||||
week = (nDayInYear - (wd - 1 + 7) % 7 + 7) / 7;
|
wdYearStart = ConvertWeekDayToMondayBase(wdYearStart);
|
||||||
}
|
wdTarget = ConvertWeekDayToMondayBase(wdTarget);
|
||||||
|
|
||||||
// FIXME some more elegant way??
|
// quoting from http://www.cl.cam.ac.uk/~mgk25/iso-time.html:
|
||||||
WeekDay wdYearStart = wxDateTime(1, Jan, GetYear()).GetWeekDay();
|
//
|
||||||
if ( wdYearStart == Wed || wdYearStart == Thu )
|
// 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
|
||||||
week++;
|
// 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 week;
|
||||||
|
@@ -323,6 +323,7 @@ for n in range(20):
|
|||||||
{ { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
|
{ { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
|
||||||
{ { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
|
{ { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
|
||||||
{ { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
|
{ { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
wxDateTime dt;
|
wxDateTime dt;
|
||||||
@@ -425,6 +426,8 @@ for n in range(20):
|
|||||||
{ { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
|
{ { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
|
||||||
{ { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
|
{ { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
|
||||||
{ { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 },
|
{ { 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++ )
|
for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )
|
||||||
|
Reference in New Issue
Block a user