]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/datetime.cpp
another try at mingw32 compilation fix
[wxWidgets.git] / src / common / datetime.cpp
index ec0c9c5ccf1c6649354124c0fa4d2feb6a1933ad..a042dd5947079c60ebd1195f8f005a958ec808b9 100644 (file)
 // Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
+// TODO: for $DEITY sake, someone please fix the #ifdef __WXWINCE__ everywhere,
+//       the proper way to do it is to implement (subset of) wxStrftime() for
+//       CE instead of this horror!!
+
 /*
  * Implementation notes:
  *
@@ -80,7 +84,9 @@
 #ifdef __WINDOWS__
     #include "wx/msw/wrapwin.h"
     #include <winnls.h>
-    #include <locale.h>
+    #ifndef __WXWINCE__
+        #include <locale.h>
+    #endif
 #endif
 
 #include "wx/datetime.h"
@@ -121,6 +127,18 @@ wxCUSTOM_TYPE_INFO(wxDateTime, wxToStringConverter<wxDateTime> , wxFromStringCon
     #undef HAVE_STRPTIME
 #endif // broken strptime()
 
+#if defined(HAVE_STRPTIME) && defined(__DARWIN__) && defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS
+    // configure detects strptime as linkable because it's in the OS X
+    // System library but MSL headers don't declare it.
+
+//    char *strptime(const char *, const char *, struct tm *);
+    // However, we DON'T want to just provide it here because we would
+    // crash and/or overwrite data when strptime from OS X tries
+    // to fill in MW's struct tm which is two fields shorter (no TZ stuff)
+    // So for now let's just say we don't have strptime
+    #undef HAVE_STRPTIME
+#endif
+
 #if defined(__MWERKS__) && wxUSE_UNICODE
     #include <wtime.h>
 #endif
@@ -353,11 +371,12 @@ static long GetTruncatedJDN(wxDateTime::wxDateTime_t day,
             - JDN_OFFSET;
 }
 
+#ifndef __WXWINCE__
 // this function is a wrapper around strftime(3) adding error checking
 static wxString CallStrftime(const wxChar *format, const tm* tm)
 {
     wxChar buf[4096];
-       if ( !wxStrftime(buf, WXSIZEOF(buf), format, tm) )
+    if ( !wxStrftime(buf, WXSIZEOF(buf), format, tm) )
     {
         // buffer is too small?
         wxFAIL_MSG(_T("strftime() failed"));
@@ -365,6 +384,7 @@ static wxString CallStrftime(const wxChar *format, const tm* tm)
 
     return wxString(buf);
 }
+#endif
 
 #ifdef HAVE_STRPTIME
 
@@ -821,47 +841,47 @@ wxString wxDateTime::GetMonthName(wxDateTime::Month month,
 
     return CallStrftime(flags == Name_Abbr ? _T("%b") : _T("%B"), &tm);
 #else
-       wxString ret;
-       switch(month)
-       {
-               case Jan: 
-                       ret = (flags == Name_Abbr ? wxT("Jan"): wxT("January"));
-                       break;
-               case Feb: 
-                       ret = (flags == Name_Abbr ? wxT("Feb"): wxT("Febuary"));
-                       break;
-               case Mar: 
-                       ret = (flags == Name_Abbr ? wxT("Mar"): wxT("March"));
-                       break;
-               case Apr: 
-                       ret = (flags == Name_Abbr ? wxT("Apr"): wxT("April"));
-                       break;
-               case May: 
-                       ret = (flags == Name_Abbr ? wxT("May"): wxT("May"));
-                       break;
-               case Jun: 
-                       ret = (flags == Name_Abbr ? wxT("Jun"): wxT("June"));
-                       break;
-               case Jul: 
-                       ret = (flags == Name_Abbr ? wxT("Jul"): wxT("July"));
-                       break;
-               case Aug: 
-                       ret = (flags == Name_Abbr ? wxT("Aug"): wxT("August"));
-                       break;
-               case Sep: 
-                       ret = (flags == Name_Abbr ? wxT("Sep"): wxT("September"));
-                       break;
-               case Oct: 
-                       ret = (flags == Name_Abbr ? wxT("Oct"): wxT("October"));
-                       break;
-               case Nov: 
-                       ret = (flags == Name_Abbr ? wxT("Nov"): wxT("November"));
-                       break;
-               case Dec: 
-                       ret = (flags == Name_Abbr ? wxT("Dec"): wxT("December"));
-                       break;
-       }
-       return ret;
+    wxString ret;
+    switch(month)
+    {
+        case Jan:
+            ret = (flags == Name_Abbr ? wxT("Jan"): wxT("January"));
+            break;
+        case Feb:
+            ret = (flags == Name_Abbr ? wxT("Feb"): wxT("Febuary"));
+            break;
+        case Mar:
+            ret = (flags == Name_Abbr ? wxT("Mar"): wxT("March"));
+            break;
+        case Apr:
+            ret = (flags == Name_Abbr ? wxT("Apr"): wxT("April"));
+            break;
+        case May:
+            ret = (flags == Name_Abbr ? wxT("May"): wxT("May"));
+            break;
+        case Jun:
+            ret = (flags == Name_Abbr ? wxT("Jun"): wxT("June"));
+            break;
+        case Jul:
+            ret = (flags == Name_Abbr ? wxT("Jul"): wxT("July"));
+            break;
+        case Aug:
+            ret = (flags == Name_Abbr ? wxT("Aug"): wxT("August"));
+            break;
+        case Sep:
+            ret = (flags == Name_Abbr ? wxT("Sep"): wxT("September"));
+            break;
+        case Oct:
+            ret = (flags == Name_Abbr ? wxT("Oct"): wxT("October"));
+            break;
+        case Nov:
+            ret = (flags == Name_Abbr ? wxT("Nov"): wxT("November"));
+            break;
+        case Dec:
+            ret = (flags == Name_Abbr ? wxT("Dec"): wxT("December"));
+            break;
+    }
+    return ret;
 #endif
 }
 
@@ -889,32 +909,32 @@ wxString wxDateTime::GetWeekDayName(wxDateTime::WeekDay wday,
     // ... and call strftime()
     return CallStrftime(flags == Name_Abbr ? _T("%a") : _T("%A"), &tm);
 #else
-       wxString ret;
-       switch(wday)
-       {
-               case Sun: 
-                       ret = (flags == Name_Abbr ? wxT("Sun") : wxT("Sunday"));
-                       break;
-               case Mon:
-                       ret = (flags == Name_Abbr ? wxT("Mon") : wxT("Monday"));
-                       break;
-               case Tue:
-                       ret = (flags == Name_Abbr ? wxT("Tue") : wxT("Tuesday"));
-                       break;
-               case Wed:
-                       ret = (flags == Name_Abbr ? wxT("Wed") : wxT("Wednesday"));
-                       break;
-               case Thu:
-                       ret = (flags == Name_Abbr ? wxT("Thu") : wxT("Thursday"));
-                       break;
-               case Fri:
-                       ret = (flags == Name_Abbr ? wxT("Fri") : wxT("Friday"));
-                       break;
-               case Sat:
-                       ret = (flags == Name_Abbr ? wxT("Sat") : wxT("Saturday"));
-                       break;
-       }
-       return ret;
+    wxString ret;
+    switch(wday)
+    {
+        case Sun:
+            ret = (flags == Name_Abbr ? wxT("Sun") : wxT("Sunday"));
+            break;
+        case Mon:
+            ret = (flags == Name_Abbr ? wxT("Mon") : wxT("Monday"));
+            break;
+        case Tue:
+            ret = (flags == Name_Abbr ? wxT("Tue") : wxT("Tuesday"));
+            break;
+        case Wed:
+            ret = (flags == Name_Abbr ? wxT("Wed") : wxT("Wednesday"));
+            break;
+        case Thu:
+            ret = (flags == Name_Abbr ? wxT("Thu") : wxT("Thursday"));
+            break;
+        case Fri:
+            ret = (flags == Name_Abbr ? wxT("Fri") : wxT("Friday"));
+            break;
+        case Sat:
+            ret = (flags == Name_Abbr ? wxT("Sat") : wxT("Saturday"));
+            break;
+    }
+    return ret;
 
 #endif
 }
@@ -935,7 +955,7 @@ void wxDateTime::GetAmPmStrings(wxString *am, wxString *pm)
     // assert, even though it is a perfectly legal use.
     if ( am )
     {
-        if (wxStrftime(buffer, sizeof buffer, _T("%p"), &tm) > 0)
+        if (wxStrftime(buffer, sizeof(buffer)/sizeof(wxChar), _T("%p"), &tm) > 0)
             *am = wxString(buffer);
         else
             *am = wxString();
@@ -943,7 +963,7 @@ void wxDateTime::GetAmPmStrings(wxString *am, wxString *pm)
     if ( pm )
     {
         tm.tm_hour = 13;
-        if (wxStrftime(buffer, sizeof buffer, _T("%p"), &tm) > 0)
+        if (wxStrftime(buffer, sizeof(buffer)/sizeof(wxChar), _T("%p"), &tm) > 0)
             *pm = wxString(buffer);
         else
             *pm = wxString();
@@ -1291,18 +1311,21 @@ wxDateTime& wxDateTime::Set(wxDateTime_t hour,
 
     wxDATETIME_CHECK( tm, _T("localtime() failed") );
 
+    // make a copy so it isn't clobbered by the call to mktime() below
+    struct tm tm1(*tm);
+
     // adjust the time
-    tm->tm_hour = hour;
-    tm->tm_min = minute;
-    tm->tm_sec = second;
+    tm1.tm_hour = hour;
+    tm1.tm_min = minute;
+    tm1.tm_sec = second;
 
     // and the DST in case it changes on this date
-    struct tm tm2(*tm);
+    struct tm tm2(tm1);
     mktime(&tm2);
-    if ( tm2.tm_isdst != tm->tm_isdst )
-        tm->tm_isdst = tm2.tm_isdst;
+    if ( tm2.tm_isdst != tm1.tm_isdst )
+        tm1.tm_isdst = tm2.tm_isdst;
 
-    (void)Set(*tm);
+    (void)Set(tm1);
 
     // and finally adjust milliseconds
     return SetMillisecond(millisec);
@@ -1379,6 +1402,8 @@ wxDateTime& wxDateTime::Set(double jdn)
 
     jdn *= MILLISECONDS_PER_DAY;
 
+    m_time.Assign(jdn);
+
     // JDNs always suppose an UTC date, so bring it back to local time zone
     // (also see GetJulianDayNumber() implementation)
     long tzDiff = GetTimeZone();
@@ -1388,9 +1413,7 @@ wxDateTime& wxDateTime::Set(double jdn)
         tzDiff -= 3600;
     }
 
-    jdn += tzDiff*1000; // tzDiff is in seconds
-
-    m_time.Assign(jdn);
+    m_time += tzDiff*1000; // tzDiff is in seconds
 
     return *this;
 }
@@ -1811,8 +1834,9 @@ wxDateTime& wxDateTime::SetToWeekDayInSameWeek(WeekDay weekday, WeekFlags flags)
 {
     wxDATETIME_CHECK( weekday != Inv_WeekDay, _T("invalid weekday") );
 
-    int wdayThis = GetWeekDay();
-    if ( weekday == wdayThis )
+    int wdayDst = weekday,
+        wdayThis = GetWeekDay();
+    if ( wdayDst == wdayThis )
     {
         // nothing to do
         return *this;
@@ -1826,21 +1850,23 @@ wxDateTime& wxDateTime::SetToWeekDayInSameWeek(WeekDay weekday, WeekFlags flags)
     // the logic below based on comparing weekday and wdayThis works if Sun (0)
     // is the first day in the week, but breaks down for Monday_First case so
     // we adjust the week days in this case
-    if( flags == Monday_First )
+    if ( flags == Monday_First )
     {
         if ( wdayThis == Sun )
             wdayThis += 7;
+        if ( wdayDst == Sun )
+            wdayDst += 7;
     }
     //else: Sunday_First, nothing to do
 
     // go forward or back in time to the day we want
-    if ( weekday < wdayThis )
+    if ( wdayDst < wdayThis )
     {
-        return Subtract(wxDateSpan::Days(wdayThis - weekday));
+        return Subtract(wxDateSpan::Days(wdayThis - wdayDst));
     }
     else // weekday > wdayThis
     {
-        return Add(wxDateSpan::Days(weekday - wdayThis));
+        return Add(wxDateSpan::Days(wdayDst - wdayThis));
     }
 }
 
@@ -2190,7 +2216,7 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const
             }
         }
 #ifndef __WXWINCE__
-       //Windows CE doesn't support strftime or wcsftime, so we use the generic implementation
+    //Windows CE doesn't support strftime or wcsftime, so we use the generic implementation
         if ( tm )
         {
             return CallStrftime(format, tm);
@@ -2405,9 +2431,9 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const
                         res += str;
                     }
 #else
-                                       //Use "%m/%d/%y %H:%M:%S" format instead
-                                       res += wxString::Format(wxT("%02d/%02d/%04d %02d:%02d:%02d"),
-                                                       tm.mon+1,tm.mday, tm.year, tm.hour, tm.min, tm.sec);
+                    //Use "%m/%d/%y %H:%M:%S" format instead
+                    res += wxString::Format(wxT("%02d/%02d/%04d %02d:%02d:%02d"),
+                            tm.mon+1,tm.mday, tm.year, tm.hour, tm.min, tm.sec);
 #endif
                     break;
 
@@ -2448,7 +2474,7 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const
 #ifndef __WXWINCE__
                     res += CallStrftime(_T("%p"), &tmTimeOnly);
 #else
-                                       res += (tmTimeOnly.tm_hour > 12) ? wxT("pm") : wxT("am");
+                    res += (tmTimeOnly.tm_hour > 12) ? wxT("pm") : wxT("am");
 #endif
                     break;
 
@@ -2475,7 +2501,7 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const
 #ifndef __WXWINCE__
                     res += CallStrftime(_T("%X"), &tmTimeOnly);
 #else
-                                       res += wxString::Format(wxT("%02d:%02d:%02d"),tm.hour, tm.min, tm.sec);
+                    res += wxString::Format(wxT("%02d:%02d:%02d"),tm.hour, tm.min, tm.sec);
 #endif
                     break;
 
@@ -2728,7 +2754,7 @@ const wxChar *wxDateTime::ParseRfc822Date(const wxChar* date)
     }
 
     // and now the interesting part: the timezone
-    int offset;
+    int offset wxDUMMY_INITIALIZE(0);
     if ( *p == _T('-') || *p == _T('+') )
     {
         // the explicit offset given: it has the form of hhmm
@@ -2831,17 +2857,26 @@ const wxChar *wxDateTime::ParseRfc822Date(const wxChar* date)
 }
 
 #ifdef __WINDOWS__
+
 // Get's current locale's date formatting string and stores it in fmt if
 // the locale is set; otherwise or in case of failure, leaves fmt unchanged
-void GetLocaleDateFormat(wxString *fmt)
+static void GetLocaleDateFormat(wxString *fmt)
 {
+    // there is no setlocale() under Windows CE, so just always query the
+    // system there
+#ifndef __WXWINCE__
     if ( strcmp(setlocale(LC_ALL, NULL), "C") != 0 )
+#endif
     {
         // The locale was programatically set to non-C. We assume that this was
         // done using wxLocale, in which case thread's current locale is also
         // set to correct LCID value and we can use GetLocaleInfo to determine
         // the correct formatting string:
+#ifdef __WXWINCE__
+        LCID lcid = LOCALE_USER_DEFAULT;
+#else
         LCID lcid = GetThreadLocale();
+#endif
         wxChar delim[5]; // fields deliminer, 4 chars max
         if ( GetLocaleInfo(lcid, LOCALE_SDATE, delim, 5) )
         {
@@ -2882,6 +2917,7 @@ void GetLocaleDateFormat(wxString *fmt)
         // try our luck with the default set above
     }
 }
+
 #endif // __WINDOWS__
 
 const wxChar *wxDateTime::ParseFormat(const wxChar *date,
@@ -3177,6 +3213,7 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
                     hour = tm.hour;
                     min = tm.min;
                 }
+                break;
 
             case _T('S'):       // second as a decimal number (00-61)
                 if ( !GetNumericToken(width, input, &num) || (num > 61) )