X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6a27c749b302e17446080bb232ef8010b60f3d00..5ac8ce9e055c56bb0b939905fa682a324ec3d300:/src/common/datetime.cpp diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 17410c7443..b211b4ee2d 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -16,6 +16,10 @@ // 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: * @@ -77,6 +81,14 @@ #include +#ifdef __WINDOWS__ + #include "wx/msw/wrapwin.h" + #include + #ifndef __WXWINCE__ + #include + #endif +#endif + #include "wx/datetime.h" #include "wx/stopwatch.h" // for wxGetLocalTimeMillis() @@ -347,6 +359,7 @@ 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) { @@ -359,6 +372,7 @@ static wxString CallStrftime(const wxChar *format, const tm* tm) return wxString(buf); } +#endif #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 ) { - 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(); @@ -937,7 +951,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(); @@ -1285,18 +1299,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); @@ -1373,6 +1390,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(); @@ -1382,9 +1401,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; } @@ -2824,6 +2841,70 @@ const wxChar *wxDateTime::ParseRfc822Date(const wxChar* date) 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) @@ -3183,11 +3264,11 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date, } #endif // HAVE_STRPTIME - // TODO query the LOCALE_IDATE setting under Win32 { wxDateTime dt; wxString fmtDate, fmtDateAlt; + if ( IsWestEuropeanCountry(GetCountry()) || GetCountry() == Russia ) { @@ -3200,6 +3281,12 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date, 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 )