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:
parent
04ce16a870
commit
89a7e1ff98
235
configure
vendored
235
configure
vendored
@ -1,5 +1,5 @@
|
||||
#! /bin/sh
|
||||
# From configure.in Id: configure.in 59561 2009-03-15 16:07:56Z KO .
|
||||
# From configure.in Id: configure.in 59905 2009-03-28 19:10:05Z VZ .
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.61 for wxWidgets 2.9.0.
|
||||
#
|
||||
@ -43806,239 +43806,6 @@ _ACEOF
|
||||
fi
|
||||
|
||||
if test "$wxUSE_DATETIME" = "yes"; then
|
||||
{ echo "$as_me:$LINENO: checking for strptime" >&5
|
||||
echo $ECHO_N "checking for strptime... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_func_strptime+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
/* Define strptime to an innocuous variant, in case <limits.h> declares strptime.
|
||||
For example, HP-UX 11i <limits.h> declares gettimeofday. */
|
||||
#define strptime innocuous_strptime
|
||||
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char strptime (); below.
|
||||
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
|
||||
<limits.h> exists even on freestanding compilers. */
|
||||
|
||||
#ifdef __STDC__
|
||||
# include <limits.h>
|
||||
#else
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#undef strptime
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char strptime ();
|
||||
/* The GNU C library defines this for functions which it implements
|
||||
to always fail with ENOSYS. Some functions are actually named
|
||||
something starting with __ and the normal name is an alias. */
|
||||
#if defined __stub_strptime || defined __stub___strptime
|
||||
choke me
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return strptime ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext &&
|
||||
$as_test_x conftest$ac_exeext; then
|
||||
ac_cv_func_strptime=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_cv_func_strptime=no
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $ac_cv_func_strptime" >&5
|
||||
echo "${ECHO_T}$ac_cv_func_strptime" >&6; }
|
||||
|
||||
if test "$ac_cv_func_strptime" = "yes"; then
|
||||
{ echo "$as_me:$LINENO: checking for strptime declaration" >&5
|
||||
echo $ECHO_N "checking for strptime declaration... $ECHO_C" >&6; }
|
||||
if test "${wx_cv_func_strptime_decl+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
|
||||
ac_ext=cpp
|
||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
#include <time.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
struct tm t;
|
||||
strptime("foo", "bar", &t);
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (ac_try="$ac_compile"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_compile") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_cxx_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest.$ac_objext; then
|
||||
wx_cv_func_strptime_decl=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
wx_cv_func_strptime_decl=no
|
||||
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
|
||||
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $wx_cv_func_strptime_decl" >&5
|
||||
echo "${ECHO_T}$wx_cv_func_strptime_decl" >&6; }
|
||||
fi
|
||||
if test "$wx_cv_func_strptime_decl" = "yes"; then
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_STRPTIME_DECL 1
|
||||
_ACEOF
|
||||
|
||||
else
|
||||
wx_strptime_decl="extern char *strptime(const char *, const char *, struct tm *);"
|
||||
fi
|
||||
if test "$ac_cv_func_strptime" = "yes"; then
|
||||
{ echo "$as_me:$LINENO: checking whether strptime() fails on invalid strings" >&5
|
||||
echo $ECHO_N "checking whether strptime() fails on invalid strings... $ECHO_C" >&6; }
|
||||
if test "${wx_cv_func_strptime_ok+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
if test "$cross_compiling" = yes; then
|
||||
wx_cv_func_strptime_ok=no
|
||||
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "confdefs.h"
|
||||
|
||||
$wx_strptime_decl
|
||||
|
||||
int main()
|
||||
{
|
||||
struct tm t;
|
||||
return !!strptime("", "%x", &t);
|
||||
}
|
||||
|
||||
_ACEOF
|
||||
rm -f conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && { ac_try='./conftest$ac_exeext'
|
||||
{ (case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_try") 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
wx_cv_func_strptime_ok=yes
|
||||
else
|
||||
echo "$as_me: program exited with status $ac_status" >&5
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
( exit $ac_status )
|
||||
wx_cv_func_strptime_ok=no
|
||||
fi
|
||||
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
|
||||
|
||||
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $wx_cv_func_strptime_ok" >&5
|
||||
echo "${ECHO_T}$wx_cv_func_strptime_ok" >&6; }
|
||||
|
||||
if test "$wx_cv_func_strptime_ok" = "yes"; then
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_STRPTIME 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
{ echo "$as_me:$LINENO: checking for timezone variable in <time.h>" >&5
|
||||
echo $ECHO_N "checking for timezone variable in <time.h>... $ECHO_C" >&6; }
|
||||
if test "${wx_cv_var_timezone+set}" = set; then
|
||||
|
59
configure.in
59
configure.in
@ -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>,
|
||||
|
@ -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):
|
||||
|
||||
|
@ -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
|
||||
|
@ -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; }
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -92,42 +92,6 @@ static const int MIN_PER_HOUR = 60;
|
||||
namespace
|
||||
{
|
||||
|
||||
#ifdef HAVE_STRPTIME
|
||||
|
||||
#if wxUSE_UNIX && !defined(HAVE_STRPTIME_DECL)
|
||||
// configure detected that we had strptime() but not its declaration,
|
||||
// provide it ourselves
|
||||
extern "C" char *strptime(const char *, const char *, struct tm *);
|
||||
#endif
|
||||
|
||||
// strptime() wrapper: call strptime() for the string starting at the given
|
||||
// iterator and fill output tm struct with the results and modify input to
|
||||
// point to the end of the string consumed by strptime() if successful,
|
||||
// otherwise return false and don't modify anything
|
||||
bool
|
||||
CallStrptime(const wxString& str,
|
||||
wxString::const_iterator& p,
|
||||
const char *fmt,
|
||||
tm *tm)
|
||||
{
|
||||
// convert from iterator to char pointer: this is simple as wxCStrData
|
||||
// already supports this
|
||||
const char * const start = str.c_str() + (p - str.begin());
|
||||
|
||||
const char * const end = strptime(start, fmt, tm);
|
||||
if ( !end )
|
||||
return false;
|
||||
|
||||
// convert back from char pointer to iterator: unfortunately we have no way
|
||||
// to do it efficiently currently so create a temporary string just to
|
||||
// compute the number of characters between start and end
|
||||
p += wxString(start, end - start).length();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // HAVE_STRPTIME
|
||||
|
||||
enum
|
||||
{
|
||||
DateLang_English = 1,
|
||||
@ -281,15 +245,13 @@ ParseFormatAt(wxString::const_iterator& p,
|
||||
// FIXME-VC6: using wxString() instead of wxEmptyString in the
|
||||
// line below results in error C2062: type 'class
|
||||
// wxString (__cdecl *)(void)' unexpected
|
||||
const wxString& fmtAlt = wxEmptyString,
|
||||
const wxString& fmtAlt2 = wxString())
|
||||
const wxString& fmtAlt = wxEmptyString)
|
||||
{
|
||||
const wxString str(p, end);
|
||||
wxString::const_iterator endParse;
|
||||
wxDateTime dt;
|
||||
if ( dt.ParseFormat(str, fmt, &endParse) ||
|
||||
(!fmtAlt.empty() && dt.ParseFormat(str, fmtAlt, &endParse)) ||
|
||||
(!fmtAlt2.empty() && dt.ParseFormat(str, fmtAlt2, &endParse)) )
|
||||
(!fmtAlt.empty() && dt.ParseFormat(str, fmtAlt, &endParse)) )
|
||||
{
|
||||
p += endParse - str.begin();
|
||||
}
|
||||
@ -901,383 +863,6 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
// 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__
|
||||
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
|
||||
// according to MSDN 80 chars is max allowed for short date format
|
||||
wxChar fmt[81];
|
||||
if ( ::GetLocaleInfo(lcid, LOCALE_SSHORTDATE, fmt, WXSIZEOF(fmt)) )
|
||||
{
|
||||
wxChar chLast = _T('\0');
|
||||
size_t lastCount = 0;
|
||||
for ( const wxChar *p = fmt; /* NUL handled inside */; p++ )
|
||||
{
|
||||
if ( *p == chLast )
|
||||
{
|
||||
lastCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ( *p )
|
||||
{
|
||||
// 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 )
|
||||
{
|
||||
switch ( chLast )
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
//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__
|
||||
|
||||
#ifdef __WXOSX__
|
||||
|
||||
#include "wx/osx/private.h"
|
||||
|
||||
// under OSX locale formats are defined using
|
||||
// http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns
|
||||
//
|
||||
// so we need a translation function, bluntly copied from the windows
|
||||
// version above and enhanced with the additional elements needed
|
||||
|
||||
static wxString TranslateFromUnicodeFormat(const wxString& fmt)
|
||||
{
|
||||
wxString fmtWX;
|
||||
|
||||
wxChar chLast = _T('\0');
|
||||
size_t lastCount = 0;
|
||||
for ( wxString::const_iterator p = fmt.begin(); /* end handled inside */; ++p )
|
||||
{
|
||||
if ( p == fmt.end() || *p == chLast )
|
||||
{
|
||||
lastCount++;
|
||||
if ( p == fmt.end() )
|
||||
break;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ( (*p).GetValue() )
|
||||
{
|
||||
// these characters come in groups, start counting them
|
||||
case _T('d'):
|
||||
case _T('M'):
|
||||
case _T('y'):
|
||||
case _T('g'):
|
||||
case _T('h'):
|
||||
case _T('H'):
|
||||
case _T('m'):
|
||||
case _T('s'):
|
||||
chLast = *p;
|
||||
lastCount = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
// first deal with any special characters we have had
|
||||
if ( lastCount )
|
||||
{
|
||||
switch ( chLast )
|
||||
{
|
||||
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('H'):
|
||||
switch ( lastCount )
|
||||
{
|
||||
case 1: // H
|
||||
case 2: // HH
|
||||
fmtWX += _T("%H");
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( _T("wrong number of 'H's") );
|
||||
}
|
||||
break;
|
||||
|
||||
case _T('h'):
|
||||
switch ( lastCount )
|
||||
{
|
||||
case 1: // h
|
||||
case 2: // hh
|
||||
fmtWX += _T("%h");
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( _T("wrong number of 'h's") );
|
||||
}
|
||||
break;
|
||||
|
||||
case _T('m'):
|
||||
switch ( lastCount )
|
||||
{
|
||||
case 1: // m
|
||||
case 2: // mm
|
||||
fmtWX += _T("%M");
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( _T("wrong number of 'm's") );
|
||||
}
|
||||
break;
|
||||
|
||||
case _T('s'):
|
||||
switch ( lastCount )
|
||||
{
|
||||
case 1: // s
|
||||
case 2: // ss
|
||||
fmtWX += _T("%S");
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( _T("wrong number of 's'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('%') )
|
||||
{
|
||||
// this one needs to be escaped
|
||||
fmtWX += _T('%');
|
||||
}
|
||||
|
||||
fmtWX += *p;
|
||||
}
|
||||
}
|
||||
|
||||
return fmtWX;
|
||||
}
|
||||
|
||||
static wxString GetLocaleDateFormat()
|
||||
{
|
||||
wxCFRef<CFLocaleRef> currentLocale( CFLocaleCopyCurrent() );
|
||||
|
||||
wxCFRef<CFDateFormatterRef> dateFormatter( CFDateFormatterCreate
|
||||
(NULL, currentLocale, kCFDateFormatterShortStyle, kCFDateFormatterNoStyle));
|
||||
wxCFStringRef cfs = wxCFRetain( CFDateFormatterGetFormat(dateFormatter ));
|
||||
return TranslateFromUnicodeFormat(cfs.AsString());
|
||||
}
|
||||
|
||||
static wxString GetLocaleFullDateFormat()
|
||||
{
|
||||
wxCFRef<CFLocaleRef> currentLocale( CFLocaleCopyCurrent() );
|
||||
|
||||
wxCFRef<CFDateFormatterRef> dateFormatter( CFDateFormatterCreate
|
||||
(NULL, currentLocale, kCFDateFormatterLongStyle, kCFDateFormatterMediumStyle));
|
||||
wxCFStringRef cfs = wxCFRetain( CFDateFormatterGetFormat(dateFormatter ));
|
||||
return TranslateFromUnicodeFormat(cfs.AsString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // __WXOSX__
|
||||
|
||||
bool
|
||||
wxDateTime::ParseFormat(const wxString& date,
|
||||
const wxString& format,
|
||||
@ -1420,72 +1005,39 @@ wxDateTime::ParseFormat(const wxString& date,
|
||||
|
||||
case _T('c'): // locale default date and time representation
|
||||
{
|
||||
#ifdef HAVE_STRPTIME
|
||||
struct tm tm;
|
||||
wxDateTime dt;
|
||||
|
||||
// try using strptime() -- it may fail even if the input is
|
||||
// correct but the date is out of range, so we will fall back
|
||||
// to our generic code anyhow
|
||||
if ( CallStrptime(date, input, "%c", &tm) )
|
||||
const wxString
|
||||
fmtDateTime = wxLocale::GetInfo(wxLOCALE_DATE_TIME_FMT);
|
||||
if ( !fmtDateTime.empty() )
|
||||
dt = ParseFormatAt(input, end, fmtDateTime);
|
||||
|
||||
if ( !dt.IsValid() )
|
||||
{
|
||||
hour = tm.tm_hour;
|
||||
min = tm.tm_min;
|
||||
sec = tm.tm_sec;
|
||||
|
||||
year = 1900 + tm.tm_year;
|
||||
mon = (Month)tm.tm_mon;
|
||||
mday = tm.tm_mday;
|
||||
// also try the format which corresponds to ctime()
|
||||
// output (i.e. the "C" locale default)
|
||||
dt = ParseFormatAt(input, end, wxS("%a %b %d %H:%M:%S %Y"));
|
||||
}
|
||||
else // strptime() failed; try generic heuristic code
|
||||
#endif // HAVE_STRPTIME
|
||||
|
||||
if ( !dt.IsValid() )
|
||||
{
|
||||
Tm tm;
|
||||
#ifdef __WXOSX__
|
||||
bool hasValidDate = false;
|
||||
wxString fmtDate = GetLocaleFullDateFormat();
|
||||
if ( !fmtDate.empty() )
|
||||
{
|
||||
const wxDateTime dt = ParseFormatAt
|
||||
(
|
||||
input,
|
||||
end,
|
||||
fmtDate
|
||||
);
|
||||
if ( dt.IsValid() )
|
||||
{
|
||||
tm = dt.GetTm();
|
||||
hasValidDate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !hasValidDate )
|
||||
#endif // __WXOSX__
|
||||
{
|
||||
// try the format which corresponds to ctime() output
|
||||
// first, then the generic date/time formats
|
||||
const wxDateTime dt = ParseFormatAt
|
||||
(
|
||||
input,
|
||||
end,
|
||||
wxS("%a %b %d %H:%M:%S %Y"),
|
||||
wxS("%x %X"),
|
||||
wxS("%X %x")
|
||||
);
|
||||
if ( !dt.IsValid() )
|
||||
return false;
|
||||
tm = dt.GetTm();
|
||||
}
|
||||
|
||||
|
||||
hour = tm.hour;
|
||||
min = tm.min;
|
||||
sec = tm.sec;
|
||||
|
||||
year = tm.year;
|
||||
mon = tm.mon;
|
||||
mday = tm.mday;
|
||||
// and finally also the two generic date/time formats
|
||||
dt = ParseFormatAt(input, end, wxS("%x %X"), wxS("%X %x"));
|
||||
}
|
||||
|
||||
if ( !dt.IsValid() )
|
||||
return false;
|
||||
|
||||
const Tm tm = dt.GetTm();
|
||||
|
||||
hour = tm.hour;
|
||||
min = tm.min;
|
||||
sec = tm.sec;
|
||||
|
||||
year = tm.year;
|
||||
mon = tm.mon;
|
||||
mday = tm.mday;
|
||||
|
||||
haveDay = haveMon = haveYear =
|
||||
haveHour = haveMin = haveSec = true;
|
||||
}
|
||||
@ -1608,7 +1160,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
||||
|
||||
haveHour = haveMin = haveSec = true;
|
||||
|
||||
Tm tm = dt.GetTm();
|
||||
const Tm tm = dt.GetTm();
|
||||
hour = tm.hour;
|
||||
min = tm.min;
|
||||
sec = tm.sec;
|
||||
@ -1625,7 +1177,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
||||
haveHour =
|
||||
haveMin = true;
|
||||
|
||||
Tm tm = dt.GetTm();
|
||||
const Tm tm = dt.GetTm();
|
||||
hour = tm.hour;
|
||||
min = tm.min;
|
||||
}
|
||||
@ -1654,7 +1206,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
||||
haveMin =
|
||||
haveSec = true;
|
||||
|
||||
Tm tm = dt.GetTm();
|
||||
const Tm tm = dt.GetTm();
|
||||
hour = tm.hour;
|
||||
min = tm.min;
|
||||
sec = tm.sec;
|
||||
@ -1674,77 +1226,41 @@ wxDateTime::ParseFormat(const wxString& date,
|
||||
break;
|
||||
|
||||
case _T('x'): // locale default date representation
|
||||
#ifdef HAVE_STRPTIME
|
||||
// try using strptime() -- it may fail even if the input is
|
||||
// correct but the date is out of range, so we will fall back
|
||||
// to our generic code anyhow
|
||||
{
|
||||
struct tm tm;
|
||||
wxString
|
||||
fmtDate = wxLocale::GetInfo(wxLOCALE_SHORT_DATE_FMT),
|
||||
fmtDateAlt = wxLocale::GetInfo(wxLOCALE_LONG_DATE_FMT);
|
||||
|
||||
if ( CallStrptime(date, input, "%x", &tm) )
|
||||
{
|
||||
haveDay = haveMon = haveYear = true;
|
||||
|
||||
year = 1900 + tm.tm_year;
|
||||
mon = (Month)tm.tm_mon;
|
||||
mday = tm.tm_mday;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // HAVE_STRPTIME
|
||||
|
||||
{
|
||||
wxString fmtDate,
|
||||
fmtDateAlt;
|
||||
|
||||
#if defined( __WINDOWS__ ) || defined( __WXOSX__ )
|
||||
// The above doesn't work for all locales, try to query
|
||||
// the OS for the right way of formatting the date:
|
||||
fmtDate = GetLocaleDateFormat();
|
||||
if ( fmtDate.empty() )
|
||||
#endif // __WINDOWS__
|
||||
{
|
||||
if ( IsWestEuropeanCountry(GetCountry()) ||
|
||||
GetCountry() == Russia )
|
||||
{
|
||||
fmtDate = _T("%d/%m/%y");
|
||||
fmtDateAlt = _T("%m/%d/%y");
|
||||
fmtDate = wxS("%d/%m/%Y");
|
||||
fmtDateAlt = wxS("%m/%d/%Y");
|
||||
}
|
||||
else // assume USA
|
||||
{
|
||||
fmtDate = _T("%m/%d/%y");
|
||||
fmtDateAlt = _T("%d/%m/%y");
|
||||
fmtDate = wxS("%m/%d/%Y");
|
||||
fmtDateAlt = wxS("%d/%m/%Y");
|
||||
}
|
||||
}
|
||||
|
||||
const wxDateTime
|
||||
dt = ParseFormatAt(input, end,
|
||||
fmtDate, fmtDateAlt);
|
||||
Tm tm;
|
||||
wxDateTime
|
||||
dt = ParseFormatAt(input, end, fmtDate, fmtDateAlt);
|
||||
|
||||
if ( !dt.IsValid() )
|
||||
{
|
||||
wxString fmtDateLong = fmtDate;
|
||||
wxString fmtDateLongAlt = fmtDateAlt;
|
||||
// try with short years too
|
||||
fmtDate.Replace("%Y","%y");
|
||||
fmtDateAlt.Replace("%Y","%y");
|
||||
dt = ParseFormatAt(input, end, fmtDate, fmtDateAlt);
|
||||
|
||||
|
||||
if ( !fmtDateLong.empty() )
|
||||
{
|
||||
fmtDateLong.Replace("%y","%Y");
|
||||
fmtDateLongAlt.Replace("%y","%Y");
|
||||
const wxDateTime dtLong = ParseFormatAt(input, end,
|
||||
fmtDateLong, fmtDateLongAlt);
|
||||
if ( !dtLong.IsValid() )
|
||||
return false;
|
||||
|
||||
tm = dtLong.GetTm();
|
||||
}
|
||||
else
|
||||
if ( !dt.IsValid() )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
tm = dt.GetTm();
|
||||
|
||||
const Tm tm = dt.GetTm();
|
||||
|
||||
haveDay =
|
||||
haveMon =
|
||||
@ -1758,29 +1274,21 @@ wxDateTime::ParseFormat(const wxString& date,
|
||||
break;
|
||||
|
||||
case _T('X'): // locale default time representation
|
||||
#ifdef HAVE_STRPTIME
|
||||
{
|
||||
// use strptime() to do it for us (FIXME !Unicode friendly)
|
||||
struct tm tm;
|
||||
if ( !CallStrptime(date, input, "%X", &tm) )
|
||||
return false;
|
||||
wxString fmtTime = wxLocale::GetInfo(wxLOCALE_TIME_FMT),
|
||||
fmtTimeAlt;
|
||||
|
||||
haveHour = haveMin = haveSec = true;
|
||||
if ( fmtTime.empty() )
|
||||
{
|
||||
// try to parse what follows as "%H:%M:%S" and, if this
|
||||
// fails, as "%I:%M:%S %p" - this should catch the most
|
||||
// common cases
|
||||
fmtTime = "%T";
|
||||
fmtTimeAlt = "%r";
|
||||
}
|
||||
|
||||
hour = tm.tm_hour;
|
||||
min = tm.tm_min;
|
||||
sec = tm.tm_sec;
|
||||
}
|
||||
#else // !HAVE_STRPTIME
|
||||
// TODO under Win32 we can query the LOCALE_ITIME system
|
||||
// setting which says whether the default time format is
|
||||
// 24 or 12 hour
|
||||
{
|
||||
// try to parse what follows as "%H:%M:%S" and, if this
|
||||
// fails, as "%I:%M:%S %p" - this should catch the most
|
||||
// common cases
|
||||
const wxDateTime
|
||||
dt = ParseFormatAt(input, end, "%T", "%r");
|
||||
dt = ParseFormatAt(input, end, fmtTime, fmtTimeAlt);
|
||||
if ( !dt.IsValid() )
|
||||
return false;
|
||||
|
||||
@ -1788,12 +1296,11 @@ wxDateTime::ParseFormat(const wxString& date,
|
||||
haveMin =
|
||||
haveSec = true;
|
||||
|
||||
Tm tm = dt.GetTm();
|
||||
const Tm tm = dt.GetTm();
|
||||
hour = tm.hour;
|
||||
min = tm.min;
|
||||
sec = tm.sec;
|
||||
}
|
||||
#endif // HAVE_STRPTIME/!HAVE_STRPTIME
|
||||
break;
|
||||
|
||||
case _T('y'): // year without century (00-99)
|
||||
@ -1823,7 +1330,9 @@ wxDateTime::ParseFormat(const wxString& date,
|
||||
break;
|
||||
|
||||
case _T('Z'): // timezone name
|
||||
wxFAIL_MSG(_T("TODO"));
|
||||
// FIXME: currently we just ignore everything that looks like a
|
||||
// time zone here
|
||||
GetAlphaToken(input, end);
|
||||
break;
|
||||
|
||||
case _T('%'): // a percent sign
|
||||
|
@ -72,7 +72,7 @@
|
||||
#include "wx/hashset.h"
|
||||
#include "wx/filesys.h"
|
||||
|
||||
#if defined(__DARWIN__)
|
||||
#if defined(__WXOSX__)
|
||||
#include "wx/osx/core/cfref.h"
|
||||
#include <CoreFoundation/CFLocale.h>
|
||||
#include "wx/osx/core/cfstring.h"
|
||||
@ -841,7 +841,7 @@ wxPluralFormsCalculator* wxPluralFormsCalculator::make(const char* s)
|
||||
//
|
||||
// This is a "low-level" class and is used only by wxMsgCatalog
|
||||
// NOTE: for the documentation of the binary catalog (.MO) files refer to
|
||||
// the GNU gettext manual:
|
||||
// the GNU gettext manual:
|
||||
// http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@ -1464,9 +1464,9 @@ bool wxMsgCatalogFile::FillHash(wxMessagesHash& hash,
|
||||
}
|
||||
|
||||
// skip this string
|
||||
// IMPORTANT: accesses to the 'data' pointer are valid only for
|
||||
// IMPORTANT: accesses to the 'data' pointer are valid only for
|
||||
// the first 'length+1' bytes (GNU specs says that the
|
||||
// final NUL is not counted in length); using wxStrnlen()
|
||||
// final NUL is not counted in length); using wxStrnlen()
|
||||
// we make sure we don't access memory beyond the valid range
|
||||
// (which otherwise may happen for invalid MO files):
|
||||
offset += wxStrnlen(str, length - offset) + 1;
|
||||
@ -2593,56 +2593,283 @@ bool wxLocale::AddCatalog(const wxString& szDomain,
|
||||
// accessors for locale-dependent data
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__WXMSW__) || defined(__WXOSX__)
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// This function translates from Unicode date formats described at
|
||||
//
|
||||
// http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns
|
||||
//
|
||||
// to strftime()-like syntax. This translation is not lossless but we try to do
|
||||
// our best.
|
||||
|
||||
static wxString TranslateFromUnicodeFormat(const wxString& fmt)
|
||||
{
|
||||
wxString fmtWX;
|
||||
fmtWX.reserve(fmt.length());
|
||||
|
||||
char chLast = '\0';
|
||||
size_t lastCount = 0;
|
||||
for ( wxString::const_iterator p = fmt.begin(); /* end handled inside */; ++p )
|
||||
{
|
||||
if ( p != fmt.end() )
|
||||
{
|
||||
if ( *p == chLast )
|
||||
{
|
||||
lastCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const wxUniChar ch = (*p).GetValue();
|
||||
if ( ch.IsAscii() && strchr("dghHmMsSy", ch) )
|
||||
{
|
||||
// these characters come in groups, start counting them
|
||||
chLast = ch;
|
||||
lastCount = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// interpret any special characters we collected so far
|
||||
if ( lastCount )
|
||||
{
|
||||
switch ( chLast )
|
||||
{
|
||||
case '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 += "%d";
|
||||
break;
|
||||
|
||||
case 3: // ddd
|
||||
fmtWX += "%a";
|
||||
break;
|
||||
|
||||
case 4: // dddd
|
||||
fmtWX += "%A";
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( "too many 'd's" );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
switch ( lastCount )
|
||||
{
|
||||
case 1: // M
|
||||
case 2: // MM
|
||||
// as for 'd' and 'dd' above
|
||||
fmtWX += "%m";
|
||||
break;
|
||||
|
||||
case 3:
|
||||
fmtWX += "%b";
|
||||
break;
|
||||
|
||||
case 4:
|
||||
fmtWX += "%B";
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( "too many 'M's" );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
switch ( lastCount )
|
||||
{
|
||||
case 1: // y
|
||||
case 2: // yy
|
||||
fmtWX += "%y";
|
||||
break;
|
||||
|
||||
case 4: // yyyy
|
||||
fmtWX += "%Y";
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( "wrong number of 'y's" );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
switch ( lastCount )
|
||||
{
|
||||
case 1: // H
|
||||
case 2: // HH
|
||||
fmtWX += "%H";
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( "wrong number of 'H's" );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
switch ( lastCount )
|
||||
{
|
||||
case 1: // h
|
||||
case 2: // hh
|
||||
fmtWX += "%h";
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( "wrong number of 'h's" );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
switch ( lastCount )
|
||||
{
|
||||
case 1: // m
|
||||
case 2: // mm
|
||||
fmtWX += "%M";
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( "wrong number of 'm's" );
|
||||
}
|
||||
break;
|
||||
|
||||
case 's':
|
||||
switch ( lastCount )
|
||||
{
|
||||
case 1: // s
|
||||
case 2: // ss
|
||||
fmtWX += "%S";
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( "wrong number of 's's" );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
// strftime() doesn't have era string,
|
||||
// ignore this format
|
||||
wxASSERT_MSG( lastCount <= 2, "too many 'g's" );
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( "unreachable" );
|
||||
}
|
||||
|
||||
chLast = '\0';
|
||||
lastCount = 0;
|
||||
}
|
||||
|
||||
if ( p == fmt.end() )
|
||||
break;
|
||||
|
||||
// not a special character so must be just a separator, treat as is
|
||||
if ( *p == _T('%') )
|
||||
{
|
||||
// this one needs to be escaped
|
||||
fmtWX += _T('%');
|
||||
}
|
||||
|
||||
fmtWX += *p;
|
||||
}
|
||||
|
||||
return fmtWX;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
#endif // __WXMSW__ || __WXOSX__
|
||||
|
||||
#if defined(__WXMSW__)
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
LCTYPE GetLCTYPEFormatFromLocalInfo(wxLocaleInfo index)
|
||||
{
|
||||
switch ( index )
|
||||
{
|
||||
case wxLOCALE_SHORT_DATE_FMT:
|
||||
return LOCALE_SSHORTDATE;
|
||||
|
||||
case wxLOCALE_LONG_DATE_FMT:
|
||||
return LOCALE_SLONGDATE;
|
||||
|
||||
case wxLOCALE_TIME_FMT:
|
||||
return LOCALE_STIMEFORMAT;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( "no matching LCTYPE" );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* static */
|
||||
wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat))
|
||||
{
|
||||
wxUint32 lcid = LOCALE_USER_DEFAULT;
|
||||
|
||||
if (wxGetLocale())
|
||||
if ( wxGetLocale() )
|
||||
{
|
||||
const wxLanguageInfo *info = GetLanguageInfo(wxGetLocale()->GetLanguage());
|
||||
const wxLanguageInfo * const
|
||||
info = GetLanguageInfo(wxGetLocale()->GetLanguage());
|
||||
if ( info )
|
||||
lcid = info->GetLCID();
|
||||
}
|
||||
|
||||
wxString str;
|
||||
wxChar buffer[256];
|
||||
size_t count;
|
||||
buffer[0] = wxS('\0');
|
||||
switch (index)
|
||||
|
||||
wxChar buf[256];
|
||||
buf[0] = wxT('\0');
|
||||
|
||||
switch ( index )
|
||||
{
|
||||
case wxLOCALE_DECIMAL_POINT:
|
||||
count = ::GetLocaleInfo(lcid, LOCALE_SDECIMAL, buffer, 256);
|
||||
if (!count)
|
||||
str << wxS(".");
|
||||
else
|
||||
str << buffer;
|
||||
if ( ::GetLocaleInfo(lcid, LOCALE_SDECIMAL, buf, WXSIZEOF(buf)) )
|
||||
str = buf;
|
||||
break;
|
||||
#if 0
|
||||
case wxSYS_LIST_SEPARATOR:
|
||||
count = ::GetLocaleInfo(lcid, LOCALE_SLIST, buffer, 256);
|
||||
if (!count)
|
||||
str << wxS(",");
|
||||
else
|
||||
str << buffer;
|
||||
|
||||
case wxLOCALE_SHORT_DATE_FMT:
|
||||
case wxLOCALE_LONG_DATE_FMT:
|
||||
case wxLOCALE_TIME_FMT:
|
||||
if ( ::GetLocaleInfo(lcid, GetLCTYPEFormatFromLocalInfo(index),
|
||||
buf, WXSIZEOF(buf)) )
|
||||
{
|
||||
return TranslateFromUnicodeFormat(buf);
|
||||
}
|
||||
break;
|
||||
case wxSYS_LEADING_ZERO: // 0 means no leading zero, 1 means leading zero
|
||||
count = ::GetLocaleInfo(lcid, LOCALE_ILZERO, buffer, 256);
|
||||
if (!count)
|
||||
str << wxS("0");
|
||||
else
|
||||
str << buffer;
|
||||
|
||||
case wxLOCALE_DATE_TIME_FMT:
|
||||
// there doesn't seem to be any specific setting for this, so just
|
||||
// combine date and time ones
|
||||
{
|
||||
const wxString datefmt = GetInfo(wxLOCALE_LONG_DATE_FMT);
|
||||
if ( datefmt.empty() )
|
||||
break;
|
||||
|
||||
const wxString timefmt = GetInfo(wxLOCALE_TIME_FMT);
|
||||
if ( timefmt.empty() )
|
||||
break;
|
||||
|
||||
str << datefmt << ' ' << timefmt;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
wxFAIL_MSG(wxS("Unknown System String !"));
|
||||
wxFAIL_MSG( "unknown wxLocaleInfo" );
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
#elif defined(__DARWIN__)
|
||||
#elif defined(__WXOSX__)
|
||||
|
||||
/* static */
|
||||
wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat))
|
||||
@ -2674,17 +2901,104 @@ wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat))
|
||||
cfstr = (CFStringRef) CFLocaleGetValue(userLocaleRef, kCFLocaleDecimalSeparator);
|
||||
break;
|
||||
|
||||
case wxLOCALE_SHORT_DATE_FMT:
|
||||
case wxLOCALE_LONG_DATE_FMT:
|
||||
case wxLOCALE_DATE_TIME_FMT:
|
||||
case wxLOCALE_TIME_FMT:
|
||||
// TODO
|
||||
return wxString();
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( "Unknown locale info" );
|
||||
cfstr = CFSTR("");
|
||||
break;
|
||||
return wxString();
|
||||
}
|
||||
|
||||
wxCFStringRef str(wxCFRetain(cfstr));
|
||||
return str.AsString();
|
||||
}
|
||||
|
||||
#else // !__WXMSW__ && !__DARWIN__
|
||||
#else // !__WXMSW__ && !__WXOSX__, assume generic POSIX
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
wxString GetDateFormatFromLangInfo(wxLocaleInfo index)
|
||||
{
|
||||
#ifdef HAVE_LANGINFO_H
|
||||
// array containing parameters for nl_langinfo() indexes by offset of index
|
||||
// from wxLOCALE_SHORT_DATE_FMT
|
||||
static const nl_item items[] =
|
||||
{
|
||||
D_FMT, D_T_FMT, D_T_FMT, T_FMT,
|
||||
};
|
||||
|
||||
const int nlidx = index - wxLOCALE_SHORT_DATE_FMT;
|
||||
if ( nlidx < 0 || nlidx >= (int)WXSIZEOF(items) )
|
||||
{
|
||||
wxFAIL_MSG( "logic error in GetInfo() code" );
|
||||
return wxString();
|
||||
}
|
||||
|
||||
const wxString fmt(nl_langinfo(items[nlidx]));
|
||||
|
||||
// just return the format returned by nl_langinfo() except for long date
|
||||
// format which we need to recover from date/time format ourselves (but not
|
||||
// if we failed completely)
|
||||
if ( fmt.empty() || index != wxLOCALE_LONG_DATE_FMT )
|
||||
return fmt;
|
||||
|
||||
// this is not 100% precise but the idea is that a typical date/time format
|
||||
// under POSIX systems is a combination of a long date format with time one
|
||||
// so we should be able to get just the long date format by removing all
|
||||
// time-specific format specifiers
|
||||
static const char *timeFmtSpecs = "HIklMpPrRsSTXzZ";
|
||||
static const char *timeSep = " :./-";
|
||||
|
||||
wxString fmtDateOnly;
|
||||
const wxString::const_iterator end = fmt.end();
|
||||
wxString::const_iterator lastSep = end;
|
||||
for ( wxString::const_iterator p = fmt.begin(); p != end; ++p )
|
||||
{
|
||||
if ( strchr(timeSep, *p) )
|
||||
{
|
||||
if ( lastSep == end )
|
||||
lastSep = p;
|
||||
|
||||
// skip it for now, we'll discard it if it's followed by a time
|
||||
// specifier later or add it to fmtDateOnly if it is not
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( *p == '%' &&
|
||||
(p + 1 != end) && strchr(timeFmtSpecs, p[1]) )
|
||||
{
|
||||
// time specified found: skip it and any preceding separators
|
||||
++p;
|
||||
lastSep = end;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( lastSep != end )
|
||||
{
|
||||
fmtDateOnly += wxString(lastSep, p);
|
||||
lastSep = end;
|
||||
}
|
||||
|
||||
fmtDateOnly += *p;
|
||||
}
|
||||
|
||||
return fmtDateOnly;
|
||||
#else // !HAVE_LANGINFO_H
|
||||
// no fallback, let the application deal with unavailability of
|
||||
// nl_langinfo() itself as there is no good way for us to do it (well, we
|
||||
// could try to reverse engineer the format from strftime() output but this
|
||||
// looks like too much trouble considering the relatively small number of
|
||||
// systems without nl_langinfo() still in use)
|
||||
return wxString();
|
||||
#endif // HAVE_LANGINFO_H/!HAVE_LANGINFO_H
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* static */
|
||||
wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat)
|
||||
@ -2693,37 +3007,44 @@ wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat)
|
||||
if ( !lc )
|
||||
return wxString();
|
||||
|
||||
switch ( cat )
|
||||
switch ( index )
|
||||
{
|
||||
case wxLOCALE_CAT_NUMBER:
|
||||
switch ( index )
|
||||
{
|
||||
case wxLOCALE_THOUSANDS_SEP:
|
||||
return lc->thousands_sep;
|
||||
case wxLOCALE_THOUSANDS_SEP:
|
||||
if ( cat == wxLOCALE_CAT_NUMBER )
|
||||
return lc->thousands_sep;
|
||||
else if ( cat == wxLOCALE_CAT_MONEY )
|
||||
return lc->mon_thousands_sep;
|
||||
|
||||
case wxLOCALE_DECIMAL_POINT:
|
||||
return lc->decimal_point;
|
||||
}
|
||||
wxFAIL_MSG( "invalid wxLocaleCategory" );
|
||||
break;
|
||||
|
||||
case wxLOCALE_CAT_MONEY:
|
||||
switch ( index )
|
||||
{
|
||||
case wxLOCALE_THOUSANDS_SEP:
|
||||
return lc->mon_thousands_sep;
|
||||
|
||||
case wxLOCALE_DECIMAL_POINT:
|
||||
return lc->mon_decimal_point;
|
||||
}
|
||||
case wxLOCALE_DECIMAL_POINT:
|
||||
if ( cat == wxLOCALE_CAT_NUMBER )
|
||||
return lc->decimal_point;
|
||||
else if ( cat == wxLOCALE_CAT_MONEY )
|
||||
return lc->mon_decimal_point;
|
||||
|
||||
wxFAIL_MSG( "invalid wxLocaleCategory" );
|
||||
break;
|
||||
|
||||
case wxLOCALE_SHORT_DATE_FMT:
|
||||
case wxLOCALE_LONG_DATE_FMT:
|
||||
case wxLOCALE_DATE_TIME_FMT:
|
||||
case wxLOCALE_TIME_FMT:
|
||||
if ( cat != wxLOCALE_CAT_DATE && cat != wxLOCALE_CAT_DEFAULT )
|
||||
{
|
||||
wxFAIL_MSG( "invalid wxLocaleCategory" );
|
||||
break;
|
||||
}
|
||||
|
||||
return GetDateFormatFromLangInfo(index);
|
||||
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( "unknown wxLocaleCategory" );
|
||||
return wxString(); // skip second assert below
|
||||
wxFAIL_MSG( "unknown wxLocaleInfo value" );
|
||||
}
|
||||
|
||||
wxFAIL_MSG( "unknown wxLocaleInfo value for this category" );
|
||||
|
||||
return wxString();
|
||||
}
|
||||
|
||||
|
@ -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") );
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user