]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/datetime.cpp
wxLocale now uses wxEncodingConverter (must be explicitly enabled)
[wxWidgets.git] / src / common / datetime.cpp
index 5e6df3b2d1e994b845a78efa1a98c6c9b47d4769..eae9bc33bfc3701125f5aa14ceaf2bdf636b8961 100644 (file)
@@ -442,14 +442,14 @@ void wxDateTime::Tm::AddMonths(int monDiff)
 void wxDateTime::Tm::AddDays(int dayDiff)
 {
     // normalize the days field
-    mday += dayDiff;
-    while ( mday < 1 )
+    while ( dayDiff + mday < 1 )
     {
         AddMonths(-1);
 
-        mday += GetNumOfDaysInMonth(year, mon);
+        dayDiff += GetNumOfDaysInMonth(year, mon);
     }
 
+    mday += dayDiff;
     while ( mday > GetNumOfDaysInMonth(year, mon) )
     {
         mday -= GetNumOfDaysInMonth(year, mon);
@@ -1035,8 +1035,7 @@ wxDateTime& wxDateTime::Set(wxDateTime_t hour,
                  _T("Invalid time in wxDateTime::Set()") );
 
     // get the current date from system
-    time_t timet = GetTimeNow();
-    struct tm *tm = localtime(&timet);
+    struct tm *tm = GetTmNow();
 
     wxCHECK_MSG( tm, wxInvalidDateTime, _T("localtime() failed") );
 
@@ -1125,15 +1124,29 @@ wxDateTime& wxDateTime::Set(double jdn)
     return *this;
 }
 
+wxDateTime& wxDateTime::ResetTime()
+{
+    Tm tm = GetTm();
+
+    if ( tm.hour || tm.min || tm.sec || tm.msec )
+    {
+        tm.msec =
+        tm.sec =
+        tm.min =
+        tm.hour = 0;
+
+        Set(tm);
+    }
+
+    return *this;
+}
+
 // ----------------------------------------------------------------------------
 // time_t <-> broken down time conversions
 // ----------------------------------------------------------------------------
 
 wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const
 {
-#ifdef __VMS__
-   int time2;
-#endif
     wxASSERT_MSG( IsValid(), _T("invalid wxDateTime") );
 
     time_t time = GetTicks();
@@ -1151,12 +1164,12 @@ wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const
         }
         else
         {
-            time += tz.GetOffset();
-#ifdef __VMS__ /* time is unsigned so VMS gives a warning on the original */
-          time2 = (int) time;
-          if ( time2 >= 0 )
+            time += (time_t)tz.GetOffset();
+#ifdef __VMS__ // time is unsigned so avoid warning
+            int time2 = (int) time;
+            if ( time2 >= 0 )
 #else
-          if ( time >= 0 )
+            if ( time >= 0 )
 #endif
             {
                 tm = gmtime(&time);
@@ -1349,6 +1362,9 @@ wxDateTime& wxDateTime::Add(const wxDateSpan& diff)
 
     Set(tm);
 
+    wxASSERT_MSG( IsSameTime(tm),
+                  _T("Add(wxDateSpan) shouldn't modify time") );
+
     return *this;
 }
 
@@ -1360,7 +1376,10 @@ wxDateTime& wxDateTime::SetToLastMonthDay(Month month,
                                           int year)
 {
     // take the current month/year if none specified
-    ReplaceDefaultYearMonthWithCurrent(&year, &month);
+    if ( year == Inv_Year )
+        year = GetYear();
+    if ( month == Inv_Month )
+        month = GetMonth();
 
     return Set(GetNumOfDaysInMonth(year, month), month, year);
 }
@@ -1508,48 +1527,50 @@ wxDateTime::wxDateTime_t wxDateTime::GetDayOfYear(const TimeZone& tz) const
     return gs_cumulatedDays[IsLeapYear(tm.year)][tm.mon] + tm.mday;
 }
 
-wxDateTime::wxDateTime_t wxDateTime::GetWeekOfYear(const TimeZone& tz) const
+wxDateTime::wxDateTime_t wxDateTime::GetWeekOfYear(wxDateTime::WeekFlags flags,
+                                                   const TimeZone& tz) const
 {
-#if 1
-    // the first week of the year is the one which contains Jan, 4 (according
-    // to ISO standard rule), so the year day N0 = 4 + 7*W always lies in the
-    // week W+1. As any day N = 7*W + 4 + (N - 4)%7, it lies in the same week
-    // as N0 or in the next one.
-
-    // TODO this surely may be optimized - I got confused while writing it
+    if ( flags == Default_First )
+    {
+        flags = GetCountry() == USA ? Sunday_First : Monday_First;
+    }
 
     wxDateTime_t nDayInYear = GetDayOfYear(tz);
+    wxDateTime_t week;
 
-    // the week day of the day lying in the first week
-    WeekDay wdayStart = wxDateTime(4, Jan, GetYear()).GetWeekDay();
-
-    wxDateTime_t week = (nDayInYear - 4) / 7 + 1;
+    WeekDay wd = GetWeekDay(tz);
+    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;
+    }
 
-    // notice that Sunday shoould be counted as 7, not 0 here!
-    if ( ((nDayInYear - 4) % 7) + (!wdayStart ? 7 : wdayStart) > 7 )
+    // FIXME some more elegant way??
+    WeekDay wdYearStart = wxDateTime(1, Jan, GetYear()).GetWeekDay();
+    if ( wdYearStart == Wed || wdYearStart == Thu )
     {
         week++;
     }
 
     return week;
-#else // 0
-    // an attempt at doing it simpler - but this doesn't quite work...
-    return (WeekDay)((GetDayOfYear(tz) - (GetWeekDay(tz) - 1 + 7) % 7 + 7) / 7);
-#endif // 0/1
 }
 
-wxDateTime::wxDateTime_t wxDateTime::GetWeekOfMonth(const TimeZone& tz) const
+wxDateTime::wxDateTime_t wxDateTime::GetWeekOfMonth(wxDateTime::WeekFlags flags,
+                                                    const TimeZone& tz) const
 {
-    size_t nWeek = 0;
-
-    wxDateTime dt(*this);
-    do
+    Tm tm = GetTm(tz);
+    wxDateTime dtMonthStart = wxDateTime(1, tm.mon, tm.year);
+    size_t nWeek = GetWeekOfYear(flags) - dtMonthStart.GetWeekOfYear(flags) + 1;
+    if ( nWeek < 0 )
     {
-        nWeek++;
-
-        dt -= wxTimeSpan::Week();
+        // this may happen for January when Jan, 1 is the last week of the
+        // previous year
+        nWeek += IsLeapYear(tm.year - 1) ? 53 : 52;
     }
-    while ( dt.GetMonth(tz) == GetMonth(tz) );
 
     return nWeek;
 }
@@ -1655,9 +1676,6 @@ wxDateTime& wxDateTime::MakeTimezone(const TimeZone& tz, bool noDST)
 
 wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const
 {
-#ifdef __VMS__
-   int time2;
-#endif
     wxCHECK_MSG( format, _T(""), _T("NULL format in wxDateTime::Format") );
 
     time_t time = GetTicks();
@@ -1677,8 +1695,8 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const
         {
             time += tz.GetOffset();
 
-#ifdef __VMS__ /* time is unsigned so VMS gives a warning on the original */
-            time2 = (int) time;
+#ifdef __VMS__ // time is unsigned so avoid the warning
+            int time2 = (int) time;
             if ( time2 >= 0 )
 #else
             if ( time >= 0 )
@@ -1936,14 +1954,11 @@ restart:
                 break;
 
             case _T('U'):       // week number in the year (Sunday 1st week day)
-                {
-                    int week = (GetDayOfYear(tz) - tm.GetWeekDay() + 7) / 7;
-                    res += wxString::Format(fmt, week);
-                }
+                res += wxString::Format(fmt, GetWeekOfYear(Sunday_First, tz));
                 break;
 
             case _T('W'):       // week number in the year (Monday 1st week day)
-                res += wxString::Format(fmt, GetWeekOfYear(tz));
+                res += wxString::Format(fmt, GetWeekOfYear(Monday_First, tz));
                 break;
 
             case _T('w'):       // weekday as a number (0-6), Sunday = 0
@@ -2896,7 +2911,7 @@ const wxChar *wxDateTime::ParseDate(const wxChar *date)
     int year = 0;
 
     // tokenize the string
-    wxStringTokenizer tok(p, _T(",/-\t "));
+    wxStringTokenizer tok(p, _T(",/-\t\n "));
     while ( tok.HasMoreTokens() )
     {
         wxString token = tok.GetNextToken();