]> git.saurik.com Git - wxWidgets.git/commitdiff
fixed GetWeekOfYear() for first/last week in some cases (patch 908793)
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 11 Sep 2004 21:37:28 +0000 (21:37 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 11 Sep 2004 21:37:28 +0000 (21:37 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@29100 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/common/datetime.cpp
tests/datetime/datetime.cpp

index 7828abd18215a0e8428a01603e5fd7c55a98f1c0..4aec62ea5c346203c21417633083a77d4ec6d20b 100644 (file)
@@ -1833,40 +1833,81 @@ bool wxDateTime::SetToWeekDay(WeekDay weekday,
     }
 }
 
+static inline
+wxDateTime::wxDateTime_t GetDayOfYearFromTm(const wxDateTime::Tm& tm)
+{
+    return gs_cumulatedDays[wxDateTime::IsLeapYear(tm.year)][tm.mon] + tm.mday;
+}
+
 wxDateTime::wxDateTime_t wxDateTime::GetDayOfYear(const TimeZone& tz) const
 {
-    Tm tm(GetTm(tz));
+    return GetDayOfYearFromTm(GetTm(tz));
+}
 
-    return gs_cumulatedDays[IsLeapYear(tm.year)][tm.mon] + tm.mday;
+// 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
+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;
index c45e0ffacda0b1a109fda1ce0e1d7316f67b7017..691a553283b0d3c15e27fedd1fbbe8f3cab4856d 100644 (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++ )