Added wxLOCALE_DATE/TIME_FMT support to wxLocale::GetInfo().

- Implement for POSIX and Win32, TODO for OS X
- Use this instead of ad hoc code in wxDateTime::ParseFormat()
- Remove HAVE_STRPTIME, we don't need nor use strptime() any more


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59914 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2009-03-29 17:15:43 +00:00
parent 04ce16a870
commit 89a7e1ff98
12 changed files with 616 additions and 964 deletions
Vendored
+1 -234
View File
File diff suppressed because it is too large Load Diff
-59
View File
@@ -5841,65 +5841,6 @@ if test "$ac_cv_func_gettimeofday" = "yes"; then
fi
if test "$wxUSE_DATETIME" = "yes"; then
dnl check for strptime and for its declaration as some systems lack it
AC_CHECK_FUNC(strptime)
if test "$ac_cv_func_strptime" = "yes"; then
AC_CACHE_CHECK([for strptime declaration], wx_cv_func_strptime_decl,
[
AC_LANG_PUSH(C++)
AC_TRY_COMPILE(
[
#include <time.h>
],
[
struct tm t;
strptime("foo", "bar", &t);
],
wx_cv_func_strptime_decl=yes,
wx_cv_func_strptime_decl=no
)
AC_LANG_POP()
]
)
fi
if test "$wx_cv_func_strptime_decl" = "yes"; then
AC_DEFINE(HAVE_STRPTIME_DECL)
else
wx_strptime_decl="extern char *strptime(const char *, const char *, struct tm *);"
fi
if test "$ac_cv_func_strptime" = "yes"; then
dnl strptime() behaviour doesn't conform to POSIX under Mac OS X <
dnl 10.5 and possibly other BSD variants, check that strptime() we
dnl have fails to parse format when the string doesn't match it instea
dnl of just stopping immediately and returning non-NULL
AC_CACHE_CHECK([whether strptime() fails on invalid strings],
wx_cv_func_strptime_ok,
[AC_RUN_IFELSE(
[
#include <stdlib.h>
#include <time.h>
#include "confdefs.h"
$wx_strptime_decl
int main()
{
struct tm t;
return !!strptime("", "%x", &t);
}
],
wx_cv_func_strptime_ok=yes,
wx_cv_func_strptime_ok=no,
dnl be pessimistic when cross-compiling
wx_cv_func_strptime_ok=no
)]
)
if test "$wx_cv_func_strptime_ok" = "yes"; then
AC_DEFINE(HAVE_STRPTIME)
fi
fi
dnl check for timezone variable
dnl doesn't exist under Darwin / Mac OS X which uses tm_gmtoff instead
AC_CACHE_CHECK(for timezone variable in <time.h>,
+1
View File
@@ -386,6 +386,7 @@ All:
- Added support of %l format specifier to wxDateTime::ParseFormat().
- wxImage handlers can now support multiple extensions (Ivan Krestinin).
- Added wxFileName::StripExtension() (troelsk).
- Added wxLOCALE_DATE/TIME_FMT support to wxLocale::GetInfo().
All (Unix):
-24
View File
@@ -139,30 +139,6 @@ extern WXDLLIMPEXP_DATA_BASE(const wxDateTime) wxDefaultDateTime;
// conditional compilation
// ----------------------------------------------------------------------------
#if defined(HAVE_STRPTIME) && defined(__GLIBC__) && \
((__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0))
// glibc 2.0.7 strptime() is broken - the following snippet causes it to
// crash (instead of just failing):
//
// strncpy(buf, "Tue Dec 21 20:25:40 1999", 128);
// strptime(buf, "%x", &tm);
//
// so don't use it
#undef HAVE_STRPTIME
#endif // broken strptime()
#if defined(HAVE_STRPTIME) && defined(__DARWIN__) && defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS
// configure detects strptime as linkable because it's in the OS X
// System library but MSL headers don't declare it.
// char *strptime(const char *, const char *, struct tm *);
// However, we DON'T want to just provide it here because we would
// crash and/or overwrite data when strptime from OS X tries
// to fill in MW's struct tm which is two fields shorter (no TZ stuff)
// So for now let's just say we don't have strptime
#undef HAVE_STRPTIME
#endif
// everyone has strftime except Win CE unless VC8 is used
#if !defined(__WXWINCE__) || defined(__VISUALC8__)
#define HAVE_STRFTIME
+19 -4
View File
@@ -364,6 +364,10 @@ enum wxLocaleCategory
// monetary value
wxLOCALE_CAT_MONEY,
// default category for wxLocaleInfo values which only apply to a single
// category (e.g. wxLOCALE_SHORT_DATE_FMT)
wxLOCALE_CAT_DEFAULT,
wxLOCALE_CAT_MAX
};
@@ -373,11 +377,21 @@ enum wxLocaleCategory
enum wxLocaleInfo
{
// the thounsands separator
// the thousands separator (for wxLOCALE_CAT_NUMBER or MONEY)
wxLOCALE_THOUSANDS_SEP,
// the character used as decimal point
wxLOCALE_DECIMAL_POINT
// the character used as decimal point (for wxLOCALE_CAT_NUMBER or MONEY)
wxLOCALE_DECIMAL_POINT,
// the stftime()-formats used for short/long date and time representations
// (under some platforms short and long date formats are the same)
//
// NB: these elements should appear in this order, code in GetInfo() relies
// on it
wxLOCALE_SHORT_DATE_FMT,
wxLOCALE_LONG_DATE_FMT,
wxLOCALE_DATE_TIME_FMT,
wxLOCALE_TIME_FMT
};
@@ -449,7 +463,8 @@ public:
// get the values of the given locale-dependent datum: the current locale
// is used, the US default value is returned if everything else fails
static wxString GetInfo(wxLocaleInfo index, wxLocaleCategory cat);
static wxString GetInfo(wxLocaleInfo index,
wxLocaleCategory cat = wxLOCALE_CAT_DEFAULT);
// return true if the locale was set successfully
bool IsOk() const { return m_pszOldLocale != NULL; }
+94 -13
View File
@@ -280,7 +280,7 @@ enum wxLayoutDirection
*/
struct WXDLLIMPEXP_BASE wxLanguageInfo
{
/// ::wxLanguage id.
/// ::wxLanguage id.
/// It should be greater than @c wxLANGUAGE_USER_DEFINED when defining your own
/// language info structure.
int Language;
@@ -314,20 +314,33 @@ struct WXDLLIMPEXP_BASE wxLanguageInfo
/**
The category of locale settings. See wxLocale::GetInfo().
The category of locale settings.
@see wxLocale::GetInfo()
*/
enum wxLocaleCategory
{
/// (any) numbers
/// Number formatting.
wxLOCALE_CAT_NUMBER,
/// date/time
/// Date/time formatting.
wxLOCALE_CAT_DATE,
/// monetary value
/// Monetary values formatting.
wxLOCALE_CAT_MONEY,
wxLOCALE_CAT_MAX
/**
Default category for the wxLocaleInfo value.
This category can be used for values which only make sense for a single
category, e.g. wxLOCALE_SHORT_DATE_FMT which can only be used with
wxLOCALE_CAT_DATE. As this is the default value of the second parameter
of wxLocale::GetInfo(), wxLOCALE_CAT_DATE can be omitted when asking
for wxLOCALE_SHORT_DATE_FMT value.
@since 2.9.0
*/
wxLOCALE_CAT_DEFAULT
};
/**
@@ -335,11 +348,70 @@ enum wxLocaleCategory
*/
enum wxLocaleInfo
{
/// The thounsands separator
/**
The thousands separator.
This value can be used with either wxLOCALE_CAT_NUMBER or
wxLOCALE_CAT_MONEY categories.
*/
wxLOCALE_THOUSANDS_SEP,
/// The character used as decimal point
wxLOCALE_DECIMAL_POINT
/**
The character used as decimal point.
This value can be used with either wxLOCALE_CAT_NUMBER or
wxLOCALE_CAT_MONEY categories.
*/
wxLOCALE_DECIMAL_POINT,
/**
The date and time formats.
The strings returned by wxLocale::GetInfo() use strftime() or,
equivalently, wxDateTime::Format() format. If the relevant format
couldn't be determined, an empty string is returned -- there is no
fallback value so that the application could determine the best course
of actions itself in such case.
All of these values are used with wxLOCALE_CAT_DATE in
wxLocale::GetInfo() or, more typically, with wxLOCALE_CAT_DEFAULT as
they only apply to a single category.
*/
//@{
/**
Short date format.
Notice that short and long date formats may be the same under POSIX
systems currently but may, and typically are, different under MSW or OS
X.
@since 2.9.0
*/
wxLOCALE_SHORT_DATE_FMT,
/**
Long date format.
@since 2.9.0
*/
wxLOCALE_LONG_DATE_FMT,
/**
Date and time format.
@since 2.9.0
*/
wxLOCALE_DATE_TIME_FMT,
/**
Time format.
@since 2.9.0
*/
wxLOCALE_TIME_FMT
//@}
};
@@ -649,7 +721,7 @@ public:
/**
Tries to detect the user's default language setting.
Returns the ::wxLanguage value or @c wxLANGUAGE_UNKNOWN if the language-guessing
algorithm failed.
*/
@@ -658,10 +730,19 @@ public:
/**
Get the values of the given locale-dependent datum.
The current locale is used, the US default value is returned if everything
else fails.
This function returns the value of the locale-specific option specified
by the given @a index.
@param index
One of the elements of wxLocaleInfo enum.
@param cat
The category to use with the given index or wxLOCALE_CAT_DEFAULT if
the index can only apply to a single category.
@return
The option value or empty string if the function failed.
*/
static wxString GetInfo(wxLocaleInfo index, wxLocaleCategory cat);
static wxString GetInfo(wxLocaleInfo index,
wxLocaleCategory cat = wxLOCALE_CAT_DEFAULT);
/**
Initializes the wxLocale instance.
-6
View File
@@ -881,12 +881,6 @@
/* define if you have statvfs function */
#undef HAVE_STATVFS
/* Define if you have strptime() */
#undef HAVE_STRPTIME
/* Define if strptime() is declared in headers */
#undef HAVE_STRPTIME_DECL
/* Define if you have strtoull() and strtoll() */
#undef HAVE_STRTOULL
-6
View File
@@ -955,12 +955,6 @@ typedef pid_t GPid;
/* define if you have statvfs function */
#undef HAVE_STATVFS
/* Define if you have strptime() */
#define HAVE_STRPTIME 1
/* Define if you have strptime() declaration */
#define HAVE_STRPTIME_DECL 1
/* Define if you have strtoull() and strtoll() */
#define HAVE_STRTOULL 1
File diff suppressed because it is too large Load Diff
+377 -56
View File
File diff suppressed because it is too large Load Diff
+10 -1
View File
@@ -691,7 +691,10 @@ void DateTimeTestCase::TestTimeFormat()
{ 6, wxDateTime::Feb, 1856, 23, 30, 00, 0.0, wxDateTime::Inv_WeekDay },
{ 6, wxDateTime::Feb, 1857, 23, 30, 00, 0.0, wxDateTime::Inv_WeekDay },
{ 29, wxDateTime::May, 2076, 18, 30, 00, 0.0, wxDateTime::Inv_WeekDay },
{ 29, wxDateTime::Feb, 2400, 02, 15, 25, 0.0, wxDateTime::Inv_WeekDay },
// FIXME: the test with 02:15:25 time doesn't pass because of DST
// computation problems, we get back 03:15:25
{ 29, wxDateTime::Feb, 2400, 04, 15, 25, 0.0, wxDateTime::Inv_WeekDay },
#if 0
// Need to add support for BCE dates.
{ 01, wxDateTime::Jan, -52, 03, 16, 47, 0.0, wxDateTime::Inv_WeekDay },
@@ -777,6 +780,12 @@ void DateTimeTestCase::TestTimeFormat()
wxDateTime dt;
#if 0
// special case which was known to fail
CPPUNIT_ASSERT( dt.ParseFormat("02/06/1856", "%x") );
CPPUNIT_ASSERT_EQUAL( 1856, dt.GetYear() );
#endif
// test partially specified dates too
wxDateTime dtDef(26, wxDateTime::Sep, 2008);
CPPUNIT_ASSERT( dt.ParseFormat("17", "%d") );
+51 -7
View File
@@ -41,10 +41,12 @@ private:
CPPUNIT_TEST_SUITE( IntlTestCase );
CPPUNIT_TEST( Domain );
CPPUNIT_TEST( Headers );
CPPUNIT_TEST( DateTimeFmt );
CPPUNIT_TEST_SUITE_END();
void Domain();
void Headers();
void DateTimeFmt();
wxLocale *m_locale;
@@ -59,14 +61,17 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( IntlTestCase, "IntlTestCase" );
void IntlTestCase::setUp()
{
if (!wxLocale::IsAvailable(wxLANGUAGE_FRENCH))
return; // you should have french support installed to run this test!
// Check that French locale is supported, this test doesn't work without it
// and all the other function need to check whether m_locale is non-NULL
// before continuing
if ( !wxLocale::IsAvailable(wxLANGUAGE_FRENCH) )
return;
wxLocale::AddCatalogLookupPathPrefix("./intl");
m_locale = new wxLocale;
CPPUNIT_ASSERT( m_locale);
CPPUNIT_ASSERT( m_locale );
// don't load default catalog, it may be unavailable:
bool loaded = m_locale->Init(wxLANGUAGE_FRENCH, wxLOCALE_CONV_ENCODING);
CPPUNIT_ASSERT( loaded );
@@ -86,7 +91,7 @@ void IntlTestCase::tearDown()
void IntlTestCase::Domain()
{
if (!m_locale)
return; // no french support installed on this system!
return;
// _() searches all domains by default:
CPPUNIT_ASSERT_EQUAL( "&Ouvrir un fichier", _("&Open bogus file") );
@@ -100,8 +105,8 @@ void IntlTestCase::Domain()
void IntlTestCase::Headers()
{
if (!m_locale)
return; // no french support installed on this system!
if ( !m_locale )
return;
CPPUNIT_ASSERT_EQUAL( "wxWindows 2.0 i18n sample", m_locale->GetHeaderValue("Project-Id-Version") );
CPPUNIT_ASSERT_EQUAL( "1999-01-13 18:19+0100", m_locale->GetHeaderValue("POT-Creation-Date") );
@@ -118,4 +123,43 @@ void IntlTestCase::Headers()
CPPUNIT_ASSERT_EQUAL( "", m_locale->GetHeaderValue("X-Not-Here") );
}
static void CompareFormats(const wxString& expected, wxString actual)
{
if ( actual.empty() )
{
// this means that GetInfo() failed which can happen, just ignore
return;
}
#ifdef __GLIBC__
// glibc uses some extensions in its formats which we need to convert to
// standard form
actual.Replace("%T", "%H:%M:%S");
actual.Replace("%e", "%d");
#endif // __GLIBC__
CPPUNIT_ASSERT_EQUAL( expected, actual );
}
void IntlTestCase::DateTimeFmt()
{
if ( !m_locale )
return;
CompareFormats( "%d.%m.%Y", m_locale->GetInfo(wxLOCALE_SHORT_DATE_FMT) );
CompareFormats( "%a %d %b %Y", m_locale->GetInfo(wxLOCALE_LONG_DATE_FMT) );
CompareFormats( "%a %d %b %Y %H:%M:%S %Z",
m_locale->GetInfo(wxLOCALE_DATE_TIME_FMT) );
CompareFormats( "%H:%M:%S", m_locale->GetInfo(wxLOCALE_TIME_FMT) );
// also test for "C" locale
setlocale(LC_ALL, "C");
CompareFormats( "%m/%d/%y", m_locale->GetInfo(wxLOCALE_SHORT_DATE_FMT) );
CompareFormats( "%a %b %d %Y", m_locale->GetInfo(wxLOCALE_LONG_DATE_FMT) );
CompareFormats( "%a %b %d %H:%M:%S %Y",
m_locale->GetInfo(wxLOCALE_DATE_TIME_FMT) );
CompareFormats( "%H:%M:%S", m_locale->GetInfo(wxLOCALE_TIME_FMT) );
}
#endif // wxUSE_INTL