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__
// 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)
// returns the string containing strftime() format used for short dates in the
// current locale or an empty string
static wxString GetLocaleDateFormat()
{
wxString fmtWX;
// there is no setlocale() under Windows CE, so just always query the
// system there
#ifndef __WXWINCE__
@@ -2877,45 +2879,139 @@ static void GetLocaleDateFormat(wxString *fmt)
#else
LCID lcid = GetThreadLocale();
#endif
wxChar delim[5]; // fields deliminer, 4 chars max
if ( GetLocaleInfo(lcid, LOCALE_SDATE, delim, 5) )
// according to MSDN 80 chars is max allowed for short date format
wxChar fmt[81];
if ( ::GetLocaleInfo(lcid, LOCALE_SSHORTDATE, fmt, WXSIZEOF(fmt)) )
{
wxChar centurybuf[2]; // use %y or %Y, 1 char max
wxChar century = 'y';
if ( GetLocaleInfo(lcid, LOCALE_ICENTURY, centurybuf, 2) )
wxChar chLast = _T('\0');
size_t lastCount = 0;
for ( const wxChar *p = fmt; /* NUL handled inside */; p++ )
{
if ( centurybuf[0] == _T('1') )
century = 'Y';
// else 'y' as above
if ( *p == chLast )
{
lastCount++;
continue;
}
wxChar order[2]; // order code, 1 char max
if ( GetLocaleInfo(lcid, LOCALE_IDATE, order, 2) )
switch ( *p )
{
if ( order[0] == _T('0') ) // M-D-Y
// these characters come in groups, start counting them
case _T('d'):
case _T('M'):
case _T('y'):
case _T('g'):
chLast = *p;
lastCount = 1;
break;
default:
// first deal with any special characters we have had
if ( lastCount )
{
*fmt = wxString::Format(_T("%%m%s%%d%s%%%c"),
delim, delim, century);
}
else if ( order[0] == _T('1') ) // D-M-Y
switch ( chLast )
{
*fmt = wxString::Format(_T("%%d%s%%m%s%%%c"),
delim, delim, century);
}
else if ( order[0] == _T('2') ) // Y-M-D
case _T('d'):
switch ( lastCount )
{
*fmt = wxString::Format(_T("%%%c%s%%m%s%%d"),
century, delim, delim);
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") );
}
else
break;
case _T('M'):
switch ( lastCount )
{
wxFAIL_MSG(_T("unexpected GetLocaleInfo return value"));
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
// try our luck with the default set above
}
//else: GetLocaleInfo() failed, leave fmtDate value unchanged and
// try our luck with the default formats
}
//else: default C locale, default formats should work
return fmtWX;
}
#endif // __WINDOWS__
@@ -3282,9 +3378,16 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
{
wxDateTime dt;
wxString fmtDate,
fmtDateAlt;
wxString fmtDate, fmtDateAlt;
#ifdef __WINDOWS__
// The above doesn't work for all locales, try to query
// Windows for the right way of formatting the date:
fmtDate = GetLocaleDateFormat();
if ( fmtDate.empty() )
#endif
{
if ( IsWestEuropeanCountry(GetCountry()) ||
GetCountry() == Russia )
{
@@ -3296,16 +3399,11 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
fmtDate = _T("%m/%d/%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 )
if ( !result && !fmtDateAlt.empty() )
{
// ok, be nice and try another one
result = dt.ParseFormat(input, fmtDateAlt);