]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/datetime.cpp
Another place we need an autorelease pool.
[wxWidgets.git] / src / common / datetime.cpp
index 948b3e6f26e3ed18f286096672a41a799f55b10d..2474382dba6d6190fe7b136e852d065d84d0b767 100644 (file)
@@ -93,17 +93,17 @@ const long wxDateTime::TIME_T_FACTOR = 1000l;
 
 template<> void wxStringReadValue(const wxString &s , wxDateTime &data )
 {
-    data.ParseFormat(s,wxT("%Y-%m-%d %H:%M:%S")) ;
+    data.ParseFormat(s,"%Y-%m-%d %H:%M:%S", NULL);
 }
 
 template<> void wxStringWriteValue(wxString &s , const wxDateTime &data )
 {
-    s = data.Format(wxT("%Y-%m-%d %H:%M:%S")) ;
+    s = data.Format("%Y-%m-%d %H:%M:%S");
 }
 
 wxCUSTOM_TYPE_INFO(wxDateTime, wxToStringConverter<wxDateTime> , wxFromStringConverter<wxDateTime>)
 
-#endif
+#endif // wxUSE_EXTENDED_RTTI
 
 //
 // ----------------------------------------------------------------------------
@@ -138,13 +138,6 @@ wxCUSTOM_TYPE_INFO(wxDateTime, wxToStringConverter<wxDateTime> , wxFromStringCon
     #include <wtime.h>
 #endif
 
-// define a special symbol for VC8 instead of writing tests for 1400 repeatedly
-#ifdef __VISUALC__
-    #if __VISUALC__ >= 1400
-        #define __VISUALC8__
-    #endif
-#endif
-
 #if !defined(WX_TIMEZONE) && !defined(WX_GMTOFF_IN_TM)
     #if defined(__WXPALMOS__)
         #define WX_GMTOFF_IN_TM
@@ -383,11 +376,14 @@ wxDateTime::Country wxDateTime::ms_country = wxDateTime::Country_Unknown;
 
 // debugger helper: shows what the date really is
 #ifdef __WXDEBUG__
-extern const wxChar *wxDumpDate(const wxDateTime* dt)
+extern const char *wxDumpDate(const wxDateTime* dt)
 {
-    static wxChar buf[128];
+    static char buf[128];
 
-    wxStrcpy(buf, dt->Format(_T("%Y-%m-%d (%a) %H:%M:%S")));
+    wxString fmt(dt->Format("%Y-%m-%d (%a) %H:%M:%S"));
+    wxStrlcpy(buf,
+              (fmt + " (" + dt->GetValue().ToString() + " ticks)").ToAscii(),
+              WXSIZEOF(buf));
 
     return buf;
 }
@@ -492,8 +488,10 @@ static wxString CallStrftime(const wxString& format, const tm* tm)
 
     if ( !wxStrftime(buf, WXSIZEOF(buf), format, tm) )
     {
-        // buffer is too small?
+        // if the format is valid, buffer must be too small?
         wxFAIL_MSG(_T("strftime() failed"));
+
+        buf[0] = '\0';
     }
 
     s = buf;
@@ -1275,6 +1273,17 @@ wxDateTime wxDateTime::GetBeginDST(int year, Country country)
                             wxFAIL_MSG( _T("no first Sunday in April?") );
                         }
                     }
+                    else if ( year > 2006 )
+                    // Energy Policy Act of 2005, Pub. L. no. 109-58, 119 Stat 594 (2005).
+                    // Starting in 2007, daylight time begins in the United States on the
+                    // second Sunday in March and ends on the first Sunday in November
+                    {
+                        if ( !dt.SetToWeekDay(Sun, 2, Mar, year) )
+                        {
+                            // weird...
+                            wxFAIL_MSG( _T("no second Sunday in March?") );
+                        }
+                    }
                     else
                     {
                         if ( !dt.SetToWeekDay(Sun, 1, Apr, year) )
@@ -1351,21 +1360,36 @@ wxDateTime wxDateTime::GetEndDST(int year, Country country)
                     dt.Set(30, Sep, year);
                     break;
 
-                default:
-                    // DST ends at 2 a.m. on the last Sunday of October
-                    if ( !dt.SetToLastWeekDay(Sun, Oct, year) )
+                default: // default for switch (year)
+                    if ( year > 2006 )
+                      // Energy Policy Act of 2005, Pub. L. no. 109-58, 119 Stat 594 (2005).
+                      // Starting in 2007, daylight time begins in the United States on the
+                      // second Sunday in March and ends on the first Sunday in November
+                    {
+                        if ( !dt.SetToWeekDay(Sun, 1, Nov, year) )
+                        {
+                            // weird...
+                            wxFAIL_MSG( _T("no first Sunday in November?") );
+                        }
+                    }
+                    else
+                     // pre-2007
+                     // DST ends at 2 a.m. on the last Sunday of October
                     {
-                        // weirder and weirder...
-                        wxFAIL_MSG( _T("no last Sunday in October?") );
+                        if ( !dt.SetToLastWeekDay(Sun, Oct, year) )
+                        {
+                            // weirder and weirder...
+                            wxFAIL_MSG( _T("no last Sunday in October?") );
+                        }
                     }
 
                     dt += wxTimeSpan::Hours(2);
 
-                    // TODO what about timezone??
+            // TODO: what about timezone??
             }
             break;
 
-        default:
+        default: // default for switch (country)
             // assume October 26th as the end of the DST - totally bogus too
             dt.Set(26, Oct, year);
     }
@@ -2852,8 +2876,9 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
     min = (wxDateTime_t)(min + *p++ - _T('0'));
 
     wxDateTime_t sec = 0;
-    if ( *p++ == _T(':') )
+    if ( *p == _T(':') )
     {
+        p++;
         if ( !wxIsdigit(*p) )
         {
             return NULL;
@@ -3161,13 +3186,15 @@ wxDateTime::ParseFormat(const wxString& date,
          haveYear = false,
          haveHour = false,
          haveMin = false,
-         haveSec = false;
+         haveSec = false,
+         haveMsec = false;
 
     bool hourIsIn12hFormat = false, // or in 24h one?
          isPM = false;              // AM by default
 
     // and the value of the items we have (init them to get rid of warnings)
-    wxDateTime_t sec = 0,
+    wxDateTime_t msec = 0,
+                 sec = 0,
                  min = 0,
                  hour = 0;
     WeekDay wday = Inv_WeekDay;
@@ -3351,6 +3378,14 @@ wxDateTime::ParseFormat(const wxString& date,
                 yday = (wxDateTime_t)num;
                 break;
 
+            case _T('l'):       // milliseconds (0-999)
+                if ( !GetNumericToken(width, input, &num) )
+                    return NULL;
+
+                haveMsec = true;
+                msec = (wxDateTime_t)num;
+                break;
+
             case _T('m'):       // month as a number (01-12)
                 if ( !GetNumericToken(width, input, &num) || !num || (num > 12) )
                 {
@@ -3574,10 +3609,11 @@ wxDateTime::ParseFormat(const wxString& date,
                     // common cases
                     wxDateTime dt;
 
-                    const wxChar *result = dt.ParseFormat(input, _T("%T"));
+                    const wxStringCharType *
+                        result = dt.ParseFormat(input, wxS("%T"));
                     if ( !result )
                     {
-                        result = dt.ParseFormat(input, _T("%r"));
+                        result = dt.ParseFormat(input, wxS("%r"));
                     }
 
                     if ( !result )
@@ -3586,7 +3622,9 @@ wxDateTime::ParseFormat(const wxString& date,
                         return NULL;
                     }
 
-                    haveHour = haveMin = haveSec = true;
+                    haveHour =
+                    haveMin =
+                    haveSec = true;
 
                     Tm tm = dt.GetTm();
                     hour = tm.hour;
@@ -3666,6 +3704,11 @@ wxDateTime::ParseFormat(const wxString& date,
     Tm tm = tmDef;
 
     // set the date
+    if ( haveMon )
+    {
+        tm.mon = mon;
+    }
+
     if ( haveYear )
     {
         tm.year = year;
@@ -3674,16 +3717,15 @@ wxDateTime::ParseFormat(const wxString& date,
     // TODO we don't check here that the values are consistent, if both year
     //      day and month/day were found, we just ignore the year day and we
     //      also always ignore the week day
-    if ( haveMon && haveDay )
+    if ( haveDay )
     {
-        if ( mday > GetNumOfDaysInMonth(tm.year, mon) )
+        if ( mday > GetNumOfDaysInMonth(tm.year, tm.mon) )
         {
             wxLogDebug(_T("bad month day in wxDateTime::ParseFormat"));
 
             return NULL;
         }
 
-        tm.mon = mon;
         tm.mday = mday;
     }
     else if ( haveYDay )
@@ -3725,6 +3767,9 @@ wxDateTime::ParseFormat(const wxString& date,
         tm.sec = sec;
     }
 
+    if ( haveMsec )
+        tm.msec = msec;
+
     Set(tm);
 
     // finally check that the week day is consistent -- if we had it
@@ -4268,6 +4313,14 @@ enum TimeSpanPart
 //  %l          milliseconds (000 - 999)
 wxString wxTimeSpan::Format(const wxString& format) const
 {
+    // we deal with only positive time spans here and just add the sign in
+    // front for the negative ones
+    if ( IsNegative() )
+    {
+        wxString str(Negate().Format(format));
+        return "-" + str;
+    }
+
     wxCHECK_MSG( !format.empty(), wxEmptyString,
                  _T("NULL format in wxTimeSpan::Format") );
 
@@ -4339,13 +4392,6 @@ wxString wxTimeSpan::Format(const wxString& format) const
                     n = GetHours();
                     if ( partBiggest < Part_Hour )
                     {
-                        if ( n < 0 )
-                        {
-                            // the sign has already been taken into account
-                            // when outputting the biggest part
-                            n = -n;
-                        }
-
                         n %= HOURS_PER_DAY;
                     }
                     else
@@ -4360,9 +4406,6 @@ wxString wxTimeSpan::Format(const wxString& format) const
                     n = GetMilliseconds().ToLong();
                     if ( partBiggest < Part_MSec )
                     {
-                        if ( n < 0 )
-                            n = -n;
-
                         n %= 1000;
                     }
                     //else: no need to reset partBiggest to Part_MSec, it is
@@ -4375,9 +4418,6 @@ wxString wxTimeSpan::Format(const wxString& format) const
                     n = GetMinutes();
                     if ( partBiggest < Part_Min )
                     {
-                        if ( n < 0 )
-                            n = -n;
-
                         n %= MIN_PER_HOUR;
                     }
                     else
@@ -4392,9 +4432,6 @@ wxString wxTimeSpan::Format(const wxString& format) const
                     n = GetSeconds().ToLong();
                     if ( partBiggest < Part_Sec )
                     {
-                        if ( n < 0 )
-                            n = -n;
-
                         n %= SEC_PER_MIN;
                     }
                     else
@@ -4408,10 +4445,6 @@ wxString wxTimeSpan::Format(const wxString& format) const
 
             if ( digits )
             {
-                // negative numbers need one extra position for '-' display
-                if ( n < 0 )
-                    digits++;
-
                 fmtPrefix << _T("0") << digits;
             }
 
@@ -4592,4 +4625,30 @@ WXDLLIMPEXP_BASE void wxPrevWDay(wxDateTime::WeekDay& wd)
                                : (wxDateTime::WeekDay)(wd - 1);
 }
 
+#ifdef __WXMSW__
+
+wxDateTime& wxDateTime::SetFromMSWSysTime(const SYSTEMTIME& st)
+{
+    return Set(st.wDay,
+            static_cast<wxDateTime::Month>(wxDateTime::Jan + st.wMonth - 1),
+            st.wYear,
+            0, 0, 0);
+}
+
+void wxDateTime::GetAsMSWSysTime(SYSTEMTIME* st) const
+{
+    const wxDateTime::Tm tm(GetTm());
+
+    st->wYear = (WXWORD)tm.year;
+    st->wMonth = (WXWORD)(tm.mon - wxDateTime::Jan + 1);
+    st->wDay = tm.mday;
+
+    st->wDayOfWeek =
+    st->wHour =
+    st->wMinute =
+    st->wSecond =
+    st->wMilliseconds = 0;
+}
+#endif // __WXMSW__
+
 #endif // wxUSE_DATETIME