]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/datetime.cpp
GTK+ 2.0 compilation.
[wxWidgets.git] / src / common / datetime.cpp
index 17410c7443abfd99cf2b28f35e021e04c56bcfc9..b211b4ee2d594689f5f9a08fdf43a75deece0184 100644 (file)
 // Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
 // 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:
  *
 /*
  * Implementation notes:
  *
 
 #include <ctype.h>
 
 
 #include <ctype.h>
 
+#ifdef __WINDOWS__
+    #include "wx/msw/wrapwin.h"
+    #include <winnls.h>
+    #ifndef __WXWINCE__
+        #include <locale.h>
+    #endif
+#endif
+
 #include "wx/datetime.h"
 #include "wx/stopwatch.h"           // for wxGetLocalTimeMillis()
 
 #include "wx/datetime.h"
 #include "wx/stopwatch.h"           // for wxGetLocalTimeMillis()
 
@@ -347,6 +359,7 @@ static long GetTruncatedJDN(wxDateTime::wxDateTime_t day,
             - JDN_OFFSET;
 }
 
             - JDN_OFFSET;
 }
 
+#ifndef __WXWINCE__
 // this function is a wrapper around strftime(3) adding error checking
 static wxString CallStrftime(const wxChar *format, const tm* tm)
 {
 // this function is a wrapper around strftime(3) adding error checking
 static wxString CallStrftime(const wxChar *format, const tm* tm)
 {
@@ -359,6 +372,7 @@ static wxString CallStrftime(const wxChar *format, const tm* tm)
 
     return wxString(buf);
 }
 
     return wxString(buf);
 }
+#endif
 
 #ifdef HAVE_STRPTIME
 
 
 #ifdef HAVE_STRPTIME
 
@@ -929,7 +943,7 @@ void wxDateTime::GetAmPmStrings(wxString *am, wxString *pm)
     // assert, even though it is a perfectly legal use.
     if ( am )
     {
     // 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();
             *am = wxString(buffer);
         else
             *am = wxString();
@@ -937,7 +951,7 @@ void wxDateTime::GetAmPmStrings(wxString *am, wxString *pm)
     if ( pm )
     {
         tm.tm_hour = 13;
     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();
             *pm = wxString(buffer);
         else
             *pm = wxString();
@@ -1285,18 +1299,21 @@ wxDateTime& wxDateTime::Set(wxDateTime_t hour,
 
     wxDATETIME_CHECK( tm, _T("localtime() failed") );
 
 
     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
     // 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
 
     // and the DST in case it changes on this date
-    struct tm tm2(*tm);
+    struct tm tm2(tm1);
     mktime(&tm2);
     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);
 
     // and finally adjust milliseconds
     return SetMillisecond(millisec);
@@ -1373,6 +1390,8 @@ wxDateTime& wxDateTime::Set(double jdn)
 
     jdn *= MILLISECONDS_PER_DAY;
 
 
     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();
     // JDNs always suppose an UTC date, so bring it back to local time zone
     // (also see GetJulianDayNumber() implementation)
     long tzDiff = GetTimeZone();
@@ -1382,9 +1401,7 @@ wxDateTime& wxDateTime::Set(double jdn)
         tzDiff -= 3600;
     }
 
         tzDiff -= 3600;
     }
 
-    jdn += tzDiff*1000; // tzDiff is in seconds
-
-    m_time.Assign(jdn);
+    m_time += tzDiff*1000; // tzDiff is in seconds
 
     return *this;
 }
 
     return *this;
 }
@@ -2824,6 +2841,70 @@ const wxChar *wxDateTime::ParseRfc822Date(const wxChar* date)
     return p;
 }
 
     return p;
 }
 
+#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
+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) )
+        {
+            wxChar centurybuf[2]; // use %y or %Y, 1 char max
+            wxChar century = 'y';
+            if ( GetLocaleInfo(lcid, LOCALE_ICENTURY, centurybuf, 2) )
+            {
+                if ( centurybuf[0] == _T('1') )
+                    century = 'Y';
+                // else 'y' as above
+            }
+
+            wxChar order[2]; // order code, 1 char max
+            if ( GetLocaleInfo(lcid, LOCALE_IDATE, order, 2) )
+            {
+                if ( order[0] == _T('0') ) // M-D-Y
+                {
+                    *fmt = wxString::Format(_T("%%m%s%%d%s%%%c"),
+                                            delim, delim, century);
+                }
+                else if ( order[0] == _T('1') ) // D-M-Y
+                {
+                    *fmt = wxString::Format(_T("%%d%s%%m%s%%%c"),
+                                            delim, delim, century);
+                }
+                else if ( order[0] == _T('2') ) // Y-M-D
+                {
+                    *fmt = wxString::Format(_T("%%%c%s%%m%s%%d"),
+                                            century, delim, delim);
+                }
+                else
+                {
+                    wxFAIL_MSG(_T("unexpected GetLocaleInfo return value"));
+                }
+            }
+        }
+        // if we failed, leave fmtDate value unchanged and
+        // try our luck with the default set above
+    }
+}
+
+#endif // __WINDOWS__
+
 const wxChar *wxDateTime::ParseFormat(const wxChar *date,
                                       const wxChar *format,
                                       const wxDateTime& dateDef)
 const wxChar *wxDateTime::ParseFormat(const wxChar *date,
                                       const wxChar *format,
                                       const wxDateTime& dateDef)
@@ -3183,11 +3264,11 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
                 }
 #endif // HAVE_STRPTIME
 
                 }
 #endif // HAVE_STRPTIME
 
-                // TODO query the LOCALE_IDATE setting under Win32
                 {
                     wxDateTime dt;
 
                     wxString fmtDate, fmtDateAlt;
                 {
                     wxDateTime dt;
 
                     wxString fmtDate, fmtDateAlt;
+
                     if ( IsWestEuropeanCountry(GetCountry()) ||
                          GetCountry() == Russia )
                     {
                     if ( IsWestEuropeanCountry(GetCountry()) ||
                          GetCountry() == Russia )
                     {
@@ -3200,6 +3281,12 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
                         fmtDateAlt = _T("%d/%m/%y");
                     }
 
                         fmtDateAlt = _T("%d/%m/%y");
                     }
 
+#ifdef __WINDOWS__
+                    // The above doesn't work for all locales, try to query
+                    // Windows for the right way of formatting the date:
+                    GetLocaleDateFormat(&fmtDate);
+#endif
+
                     const wxChar *result = dt.ParseFormat(input, fmtDate);
 
                     if ( !result )
                     const wxChar *result = dt.ParseFormat(input, fmtDate);
 
                     if ( !result )