// 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:
*
#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()
- JDN_OFFSET;
}
+#ifndef __WXWINCE__
// this function is a wrapper around strftime(3) adding error checking
static wxString CallStrftime(const wxChar *format, const tm* tm)
{
return wxString(buf);
}
+#endif
#ifdef HAVE_STRPTIME
// 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();
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();
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);
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();
tzDiff -= 3600;
}
- jdn += tzDiff*1000; // tzDiff is in seconds
-
- m_time.Assign(jdn);
+ m_time += tzDiff*1000; // tzDiff is in seconds
return *this;
}
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)
}
#endif // HAVE_STRPTIME
- // TODO query the LOCALE_IDATE setting under Win32
{
wxDateTime dt;
wxString fmtDate, fmtDateAlt;
+
if ( IsWestEuropeanCountry(GetCountry()) ||
GetCountry() == Russia )
{
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 )