fixed GetLocaleDateFormat() to work with all locales, not just ones using only , and

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33985 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2005-05-08 23:35:34 +00:00
parent 51c432b77a
commit be4e7abf54

View File

@@ -2858,10 +2858,12 @@ const wxChar *wxDateTime::ParseRfc822Date(const wxChar* date)
#ifdef __WINDOWS__ #ifdef __WINDOWS__
// Get's current locale's date formatting string and stores it in fmt if // returns the string containing strftime() format used for short dates in the
// the locale is set; otherwise or in case of failure, leaves fmt unchanged // current locale or an empty string
static void GetLocaleDateFormat(wxString *fmt) static wxString GetLocaleDateFormat()
{ {
wxString fmtWX;
// there is no setlocale() under Windows CE, so just always query the // there is no setlocale() under Windows CE, so just always query the
// system there // system there
#ifndef __WXWINCE__ #ifndef __WXWINCE__
@@ -2877,45 +2879,139 @@ static void GetLocaleDateFormat(wxString *fmt)
#else #else
LCID lcid = GetThreadLocale(); LCID lcid = GetThreadLocale();
#endif #endif
wxChar delim[5]; // fields deliminer, 4 chars max // according to MSDN 80 chars is max allowed for short date format
if ( GetLocaleInfo(lcid, LOCALE_SDATE, delim, 5) ) wxChar fmt[81];
if ( ::GetLocaleInfo(lcid, LOCALE_SSHORTDATE, fmt, WXSIZEOF(fmt)) )
{ {
wxChar centurybuf[2]; // use %y or %Y, 1 char max wxChar chLast = _T('\0');
wxChar century = 'y'; size_t lastCount = 0;
if ( GetLocaleInfo(lcid, LOCALE_ICENTURY, centurybuf, 2) ) for ( const wxChar *p = fmt; /* NUL handled inside */; p++ )
{ {
if ( centurybuf[0] == _T('1') ) if ( *p == chLast )
century = 'Y'; {
// else 'y' as above lastCount++;
} continue;
}
wxChar order[2]; // order code, 1 char max switch ( *p )
if ( GetLocaleInfo(lcid, LOCALE_IDATE, order, 2) )
{
if ( order[0] == _T('0') ) // M-D-Y
{ {
*fmt = wxString::Format(_T("%%m%s%%d%s%%%c"), // these characters come in groups, start counting them
delim, delim, century); case _T('d'):
} case _T('M'):
else if ( order[0] == _T('1') ) // D-M-Y case _T('y'):
{ case _T('g'):
*fmt = wxString::Format(_T("%%d%s%%m%s%%%c"), chLast = *p;
delim, delim, century); lastCount = 1;
} break;
else if ( order[0] == _T('2') ) // Y-M-D
{ default:
*fmt = wxString::Format(_T("%%%c%s%%m%s%%d"), // first deal with any special characters we have had
century, delim, delim); if ( lastCount )
} {
else switch ( chLast )
{ {
wxFAIL_MSG(_T("unexpected GetLocaleInfo return value")); case _T('d'):
switch ( lastCount )
{
case 1: // d
case 2: // dd
// these two are the same as we
// don't distinguish between 1 and
// 2 digits for days
fmtWX += _T("%d");
break;
case 3: // ddd
fmtWX += _T("%a");
break;
case 4: // dddd
fmtWX += _T("%A");
break;
default:
wxFAIL_MSG( _T("too many 'd's") );
}
break;
case _T('M'):
switch ( lastCount )
{
case 1: // M
case 2: // MM
// as for 'd' and 'dd' above
fmtWX += _T("%m");
break;
case 3:
fmtWX += _T("%b");
break;
case 4:
fmtWX += _T("%B");
break;
default:
wxFAIL_MSG( _T("too many 'M's") );
}
break;
case _T('y'):
switch ( lastCount )
{
case 1: // y
case 2: // yy
fmtWX += _T("%y");
break;
case 4: // yyyy
fmtWX += _T("%Y");
break;
default:
wxFAIL_MSG( _T("wrong number of 'y's") );
}
break;
case _T('g'):
// strftime() doesn't have era string,
// ignore this format
wxASSERT_MSG( lastCount <= 2,
_T("too many 'g's") );
break;
default:
wxFAIL_MSG( _T("unreachable") );
}
chLast = _T('\0');
lastCount = 0;
}
// not a special character so must be just a separator,
// treat as is
if ( *p != _T('\0') )
{
if ( *p == _T('%') )
{
// this one needs to be escaped
fmtWX += _T('%');
}
fmtWX += *p;
}
} }
if ( *p == _T('\0') )
break;
} }
} }
// if we failed, leave fmtDate value unchanged and //else: GetLocaleInfo() failed, leave fmtDate value unchanged and
// try our luck with the default set above // try our luck with the default formats
} }
//else: default C locale, default formats should work
return fmtWX;
} }
#endif // __WINDOWS__ #endif // __WINDOWS__
@@ -3282,30 +3378,32 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
{ {
wxDateTime dt; wxDateTime dt;
wxString fmtDate,
wxString fmtDate, fmtDateAlt; fmtDateAlt;
if ( IsWestEuropeanCountry(GetCountry()) ||
GetCountry() == Russia )
{
fmtDate = _T("%d/%m/%y");
fmtDateAlt = _T("%m/%d/%y");
}
else // assume USA
{
fmtDate = _T("%m/%d/%y");
fmtDateAlt = _T("%d/%m/%y");
}
#ifdef __WINDOWS__ #ifdef __WINDOWS__
// The above doesn't work for all locales, try to query // The above doesn't work for all locales, try to query
// Windows for the right way of formatting the date: // Windows for the right way of formatting the date:
GetLocaleDateFormat(&fmtDate); fmtDate = GetLocaleDateFormat();
if ( fmtDate.empty() )
#endif #endif
{
if ( IsWestEuropeanCountry(GetCountry()) ||
GetCountry() == Russia )
{
fmtDate = _T("%d/%m/%y");
fmtDateAlt = _T("%m/%d/%y");
}
else // assume USA
{
fmtDate = _T("%m/%d/%y");
fmtDateAlt = _T("%d/%m/%y");
}
}
const wxChar *result = dt.ParseFormat(input, fmtDate); const wxChar *result = dt.ParseFormat(input, fmtDate);
if ( !result ) if ( !result && !fmtDateAlt.empty() )
{ {
// ok, be nice and try another one // ok, be nice and try another one
result = dt.ParseFormat(input, fmtDateAlt); result = dt.ParseFormat(input, fmtDateAlt);