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:
235
configure
vendored
235
configure
vendored
@@ -1,5 +1,5 @@
|
|||||||
#! /bin/sh
|
#! /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.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.61 for wxWidgets 2.9.0.
|
# Generated by GNU Autoconf 2.61 for wxWidgets 2.9.0.
|
||||||
#
|
#
|
||||||
@@ -43806,239 +43806,6 @@ _ACEOF
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$wxUSE_DATETIME" = "yes"; then
|
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 "$as_me:$LINENO: checking for timezone variable in <time.h>" >&5
|
||||||
echo $ECHO_N "checking for timezone variable in <time.h>... $ECHO_C" >&6; }
|
echo $ECHO_N "checking for timezone variable in <time.h>... $ECHO_C" >&6; }
|
||||||
if test "${wx_cv_var_timezone+set}" = set; then
|
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
|
fi
|
||||||
|
|
||||||
if test "$wxUSE_DATETIME" = "yes"; then
|
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 check for timezone variable
|
||||||
dnl doesn't exist under Darwin / Mac OS X which uses tm_gmtoff instead
|
dnl doesn't exist under Darwin / Mac OS X which uses tm_gmtoff instead
|
||||||
AC_CACHE_CHECK(for timezone variable in <time.h>,
|
AC_CACHE_CHECK(for timezone variable in <time.h>,
|
||||||
|
@@ -386,6 +386,7 @@ All:
|
|||||||
- Added support of %l format specifier to wxDateTime::ParseFormat().
|
- Added support of %l format specifier to wxDateTime::ParseFormat().
|
||||||
- wxImage handlers can now support multiple extensions (Ivan Krestinin).
|
- wxImage handlers can now support multiple extensions (Ivan Krestinin).
|
||||||
- Added wxFileName::StripExtension() (troelsk).
|
- Added wxFileName::StripExtension() (troelsk).
|
||||||
|
- Added wxLOCALE_DATE/TIME_FMT support to wxLocale::GetInfo().
|
||||||
|
|
||||||
All (Unix):
|
All (Unix):
|
||||||
|
|
||||||
|
@@ -139,30 +139,6 @@ extern WXDLLIMPEXP_DATA_BASE(const wxDateTime) wxDefaultDateTime;
|
|||||||
// conditional compilation
|
// 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
|
// everyone has strftime except Win CE unless VC8 is used
|
||||||
#if !defined(__WXWINCE__) || defined(__VISUALC8__)
|
#if !defined(__WXWINCE__) || defined(__VISUALC8__)
|
||||||
#define HAVE_STRFTIME
|
#define HAVE_STRFTIME
|
||||||
|
@@ -364,6 +364,10 @@ enum wxLocaleCategory
|
|||||||
// monetary value
|
// monetary value
|
||||||
wxLOCALE_CAT_MONEY,
|
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
|
wxLOCALE_CAT_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -373,11 +377,21 @@ enum wxLocaleCategory
|
|||||||
|
|
||||||
enum wxLocaleInfo
|
enum wxLocaleInfo
|
||||||
{
|
{
|
||||||
// the thounsands separator
|
// the thousands separator (for wxLOCALE_CAT_NUMBER or MONEY)
|
||||||
wxLOCALE_THOUSANDS_SEP,
|
wxLOCALE_THOUSANDS_SEP,
|
||||||
|
|
||||||
// the character used as decimal point
|
// the character used as decimal point (for wxLOCALE_CAT_NUMBER or MONEY)
|
||||||
wxLOCALE_DECIMAL_POINT
|
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
|
// get the values of the given locale-dependent datum: the current locale
|
||||||
// is used, the US default value is returned if everything else fails
|
// 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
|
// return true if the locale was set successfully
|
||||||
bool IsOk() const { return m_pszOldLocale != NULL; }
|
bool IsOk() const { return m_pszOldLocale != NULL; }
|
||||||
|
@@ -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
|
enum wxLocaleCategory
|
||||||
{
|
{
|
||||||
/// (any) numbers
|
/// Number formatting.
|
||||||
wxLOCALE_CAT_NUMBER,
|
wxLOCALE_CAT_NUMBER,
|
||||||
|
|
||||||
/// date/time
|
/// Date/time formatting.
|
||||||
wxLOCALE_CAT_DATE,
|
wxLOCALE_CAT_DATE,
|
||||||
|
|
||||||
/// monetary value
|
/// Monetary values formatting.
|
||||||
wxLOCALE_CAT_MONEY,
|
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
|
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,
|
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
|
||||||
|
|
||||||
|
//@}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -658,10 +730,19 @@ public:
|
|||||||
/**
|
/**
|
||||||
Get the values of the given locale-dependent datum.
|
Get the values of the given locale-dependent datum.
|
||||||
|
|
||||||
The current locale is used, the US default value is returned if everything
|
This function returns the value of the locale-specific option specified
|
||||||
else fails.
|
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.
|
Initializes the wxLocale instance.
|
||||||
|
@@ -881,12 +881,6 @@
|
|||||||
/* define if you have statvfs function */
|
/* define if you have statvfs function */
|
||||||
#undef HAVE_STATVFS
|
#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() */
|
/* Define if you have strtoull() and strtoll() */
|
||||||
#undef HAVE_STRTOULL
|
#undef HAVE_STRTOULL
|
||||||
|
|
||||||
|
@@ -955,12 +955,6 @@ typedef pid_t GPid;
|
|||||||
/* define if you have statvfs function */
|
/* define if you have statvfs function */
|
||||||
#undef HAVE_STATVFS
|
#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 if you have strtoull() and strtoll() */
|
||||||
#define HAVE_STRTOULL 1
|
#define HAVE_STRTOULL 1
|
||||||
|
|
||||||
|
@@ -92,42 +92,6 @@ static const int MIN_PER_HOUR = 60;
|
|||||||
namespace
|
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
|
enum
|
||||||
{
|
{
|
||||||
DateLang_English = 1,
|
DateLang_English = 1,
|
||||||
@@ -281,15 +245,13 @@ ParseFormatAt(wxString::const_iterator& p,
|
|||||||
// FIXME-VC6: using wxString() instead of wxEmptyString in the
|
// FIXME-VC6: using wxString() instead of wxEmptyString in the
|
||||||
// line below results in error C2062: type 'class
|
// line below results in error C2062: type 'class
|
||||||
// wxString (__cdecl *)(void)' unexpected
|
// wxString (__cdecl *)(void)' unexpected
|
||||||
const wxString& fmtAlt = wxEmptyString,
|
const wxString& fmtAlt = wxEmptyString)
|
||||||
const wxString& fmtAlt2 = wxString())
|
|
||||||
{
|
{
|
||||||
const wxString str(p, end);
|
const wxString str(p, end);
|
||||||
wxString::const_iterator endParse;
|
wxString::const_iterator endParse;
|
||||||
wxDateTime dt;
|
wxDateTime dt;
|
||||||
if ( dt.ParseFormat(str, fmt, &endParse) ||
|
if ( dt.ParseFormat(str, fmt, &endParse) ||
|
||||||
(!fmtAlt.empty() && dt.ParseFormat(str, fmtAlt, &endParse)) ||
|
(!fmtAlt.empty() && dt.ParseFormat(str, fmtAlt, &endParse)) )
|
||||||
(!fmtAlt2.empty() && dt.ParseFormat(str, fmtAlt2, &endParse)) )
|
|
||||||
{
|
{
|
||||||
p += endParse - str.begin();
|
p += endParse - str.begin();
|
||||||
}
|
}
|
||||||
@@ -901,383 +863,6 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
|
|||||||
return true;
|
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
|
bool
|
||||||
wxDateTime::ParseFormat(const wxString& date,
|
wxDateTime::ParseFormat(const wxString& date,
|
||||||
const wxString& format,
|
const wxString& format,
|
||||||
@@ -1420,62 +1005,30 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
|
|
||||||
case _T('c'): // locale default date and time representation
|
case _T('c'): // locale default date and time representation
|
||||||
{
|
{
|
||||||
#ifdef HAVE_STRPTIME
|
wxDateTime dt;
|
||||||
struct tm tm;
|
|
||||||
|
|
||||||
// try using strptime() -- it may fail even if the input is
|
const wxString
|
||||||
// correct but the date is out of range, so we will fall back
|
fmtDateTime = wxLocale::GetInfo(wxLOCALE_DATE_TIME_FMT);
|
||||||
// to our generic code anyhow
|
if ( !fmtDateTime.empty() )
|
||||||
if ( CallStrptime(date, input, "%c", &tm) )
|
dt = ParseFormatAt(input, end, fmtDateTime);
|
||||||
{
|
|
||||||
hour = tm.tm_hour;
|
|
||||||
min = tm.tm_min;
|
|
||||||
sec = tm.tm_sec;
|
|
||||||
|
|
||||||
year = 1900 + tm.tm_year;
|
if ( !dt.IsValid() )
|
||||||
mon = (Month)tm.tm_mon;
|
|
||||||
mday = tm.tm_mday;
|
|
||||||
}
|
|
||||||
else // strptime() failed; try generic heuristic code
|
|
||||||
#endif // HAVE_STRPTIME
|
|
||||||
{
|
{
|
||||||
Tm tm;
|
// also try the format which corresponds to ctime()
|
||||||
#ifdef __WXOSX__
|
// output (i.e. the "C" locale default)
|
||||||
bool hasValidDate = false;
|
dt = ParseFormatAt(input, end, wxS("%a %b %d %H:%M:%S %Y"));
|
||||||
wxString fmtDate = GetLocaleFullDateFormat();
|
|
||||||
if ( !fmtDate.empty() )
|
|
||||||
{
|
|
||||||
const wxDateTime dt = ParseFormatAt
|
|
||||||
(
|
|
||||||
input,
|
|
||||||
end,
|
|
||||||
fmtDate
|
|
||||||
);
|
|
||||||
if ( dt.IsValid() )
|
|
||||||
{
|
|
||||||
tm = dt.GetTm();
|
|
||||||
hasValidDate = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !hasValidDate )
|
if ( !dt.IsValid() )
|
||||||
#endif // __WXOSX__
|
|
||||||
{
|
{
|
||||||
// try the format which corresponds to ctime() output
|
// and finally also the two generic date/time formats
|
||||||
// first, then the generic date/time formats
|
dt = ParseFormatAt(input, end, wxS("%x %X"), wxS("%X %x"));
|
||||||
const wxDateTime dt = ParseFormatAt
|
}
|
||||||
(
|
|
||||||
input,
|
|
||||||
end,
|
|
||||||
wxS("%a %b %d %H:%M:%S %Y"),
|
|
||||||
wxS("%x %X"),
|
|
||||||
wxS("%X %x")
|
|
||||||
);
|
|
||||||
if ( !dt.IsValid() )
|
if ( !dt.IsValid() )
|
||||||
return false;
|
return false;
|
||||||
tm = dt.GetTm();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const Tm tm = dt.GetTm();
|
||||||
|
|
||||||
hour = tm.hour;
|
hour = tm.hour;
|
||||||
min = tm.min;
|
min = tm.min;
|
||||||
@@ -1484,7 +1037,6 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
year = tm.year;
|
year = tm.year;
|
||||||
mon = tm.mon;
|
mon = tm.mon;
|
||||||
mday = tm.mday;
|
mday = tm.mday;
|
||||||
}
|
|
||||||
|
|
||||||
haveDay = haveMon = haveYear =
|
haveDay = haveMon = haveYear =
|
||||||
haveHour = haveMin = haveSec = true;
|
haveHour = haveMin = haveSec = true;
|
||||||
@@ -1608,7 +1160,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
|
|
||||||
haveHour = haveMin = haveSec = true;
|
haveHour = haveMin = haveSec = true;
|
||||||
|
|
||||||
Tm tm = dt.GetTm();
|
const Tm tm = dt.GetTm();
|
||||||
hour = tm.hour;
|
hour = tm.hour;
|
||||||
min = tm.min;
|
min = tm.min;
|
||||||
sec = tm.sec;
|
sec = tm.sec;
|
||||||
@@ -1625,7 +1177,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
haveHour =
|
haveHour =
|
||||||
haveMin = true;
|
haveMin = true;
|
||||||
|
|
||||||
Tm tm = dt.GetTm();
|
const Tm tm = dt.GetTm();
|
||||||
hour = tm.hour;
|
hour = tm.hour;
|
||||||
min = tm.min;
|
min = tm.min;
|
||||||
}
|
}
|
||||||
@@ -1654,7 +1206,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
haveMin =
|
haveMin =
|
||||||
haveSec = true;
|
haveSec = true;
|
||||||
|
|
||||||
Tm tm = dt.GetTm();
|
const Tm tm = dt.GetTm();
|
||||||
hour = tm.hour;
|
hour = tm.hour;
|
||||||
min = tm.min;
|
min = tm.min;
|
||||||
sec = tm.sec;
|
sec = tm.sec;
|
||||||
@@ -1674,77 +1226,41 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case _T('x'): // locale default date representation
|
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() )
|
if ( fmtDate.empty() )
|
||||||
#endif // __WINDOWS__
|
|
||||||
{
|
{
|
||||||
if ( IsWestEuropeanCountry(GetCountry()) ||
|
if ( IsWestEuropeanCountry(GetCountry()) ||
|
||||||
GetCountry() == Russia )
|
GetCountry() == Russia )
|
||||||
{
|
{
|
||||||
fmtDate = _T("%d/%m/%y");
|
fmtDate = wxS("%d/%m/%Y");
|
||||||
fmtDateAlt = _T("%m/%d/%y");
|
fmtDateAlt = wxS("%m/%d/%Y");
|
||||||
}
|
}
|
||||||
else // assume USA
|
else // assume USA
|
||||||
{
|
{
|
||||||
fmtDate = _T("%m/%d/%y");
|
fmtDate = wxS("%m/%d/%Y");
|
||||||
fmtDateAlt = _T("%d/%m/%y");
|
fmtDateAlt = wxS("%d/%m/%Y");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxDateTime
|
wxDateTime
|
||||||
dt = ParseFormatAt(input, end,
|
dt = ParseFormatAt(input, end, fmtDate, fmtDateAlt);
|
||||||
fmtDate, fmtDateAlt);
|
|
||||||
Tm tm;
|
|
||||||
|
|
||||||
if ( !dt.IsValid() )
|
if ( !dt.IsValid() )
|
||||||
{
|
{
|
||||||
wxString fmtDateLong = fmtDate;
|
// try with short years too
|
||||||
wxString fmtDateLongAlt = fmtDateAlt;
|
fmtDate.Replace("%Y","%y");
|
||||||
|
fmtDateAlt.Replace("%Y","%y");
|
||||||
|
dt = ParseFormatAt(input, end, fmtDate, fmtDateAlt);
|
||||||
|
|
||||||
|
if ( !dt.IsValid() )
|
||||||
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
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
tm = dt.GetTm();
|
const Tm tm = dt.GetTm();
|
||||||
|
|
||||||
haveDay =
|
haveDay =
|
||||||
haveMon =
|
haveMon =
|
||||||
@@ -1758,29 +1274,21 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case _T('X'): // locale default time representation
|
case _T('X'): // locale default time representation
|
||||||
#ifdef HAVE_STRPTIME
|
|
||||||
{
|
{
|
||||||
// use strptime() to do it for us (FIXME !Unicode friendly)
|
wxString fmtTime = wxLocale::GetInfo(wxLOCALE_TIME_FMT),
|
||||||
struct tm tm;
|
fmtTimeAlt;
|
||||||
if ( !CallStrptime(date, input, "%X", &tm) )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
haveHour = haveMin = haveSec = true;
|
if ( fmtTime.empty() )
|
||||||
|
|
||||||
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
|
// try to parse what follows as "%H:%M:%S" and, if this
|
||||||
// fails, as "%I:%M:%S %p" - this should catch the most
|
// fails, as "%I:%M:%S %p" - this should catch the most
|
||||||
// common cases
|
// common cases
|
||||||
|
fmtTime = "%T";
|
||||||
|
fmtTimeAlt = "%r";
|
||||||
|
}
|
||||||
|
|
||||||
const wxDateTime
|
const wxDateTime
|
||||||
dt = ParseFormatAt(input, end, "%T", "%r");
|
dt = ParseFormatAt(input, end, fmtTime, fmtTimeAlt);
|
||||||
if ( !dt.IsValid() )
|
if ( !dt.IsValid() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -1788,12 +1296,11 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
haveMin =
|
haveMin =
|
||||||
haveSec = true;
|
haveSec = true;
|
||||||
|
|
||||||
Tm tm = dt.GetTm();
|
const Tm tm = dt.GetTm();
|
||||||
hour = tm.hour;
|
hour = tm.hour;
|
||||||
min = tm.min;
|
min = tm.min;
|
||||||
sec = tm.sec;
|
sec = tm.sec;
|
||||||
}
|
}
|
||||||
#endif // HAVE_STRPTIME/!HAVE_STRPTIME
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case _T('y'): // year without century (00-99)
|
case _T('y'): // year without century (00-99)
|
||||||
@@ -1823,7 +1330,9 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case _T('Z'): // timezone name
|
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;
|
break;
|
||||||
|
|
||||||
case _T('%'): // a percent sign
|
case _T('%'): // a percent sign
|
||||||
|
@@ -72,7 +72,7 @@
|
|||||||
#include "wx/hashset.h"
|
#include "wx/hashset.h"
|
||||||
#include "wx/filesys.h"
|
#include "wx/filesys.h"
|
||||||
|
|
||||||
#if defined(__DARWIN__)
|
#if defined(__WXOSX__)
|
||||||
#include "wx/osx/core/cfref.h"
|
#include "wx/osx/core/cfref.h"
|
||||||
#include <CoreFoundation/CFLocale.h>
|
#include <CoreFoundation/CFLocale.h>
|
||||||
#include "wx/osx/core/cfstring.h"
|
#include "wx/osx/core/cfstring.h"
|
||||||
@@ -2593,56 +2593,283 @@ bool wxLocale::AddCatalog(const wxString& szDomain,
|
|||||||
// accessors for locale-dependent data
|
// 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__)
|
#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 */
|
/* static */
|
||||||
wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat))
|
wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat))
|
||||||
{
|
{
|
||||||
wxUint32 lcid = LOCALE_USER_DEFAULT;
|
wxUint32 lcid = LOCALE_USER_DEFAULT;
|
||||||
|
if ( wxGetLocale() )
|
||||||
if (wxGetLocale())
|
|
||||||
{
|
{
|
||||||
const wxLanguageInfo *info = GetLanguageInfo(wxGetLocale()->GetLanguage());
|
const wxLanguageInfo * const
|
||||||
|
info = GetLanguageInfo(wxGetLocale()->GetLanguage());
|
||||||
if ( info )
|
if ( info )
|
||||||
lcid = info->GetLCID();
|
lcid = info->GetLCID();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString str;
|
wxString str;
|
||||||
wxChar buffer[256];
|
|
||||||
size_t count;
|
wxChar buf[256];
|
||||||
buffer[0] = wxS('\0');
|
buf[0] = wxT('\0');
|
||||||
switch (index)
|
|
||||||
|
switch ( index )
|
||||||
{
|
{
|
||||||
case wxLOCALE_DECIMAL_POINT:
|
case wxLOCALE_DECIMAL_POINT:
|
||||||
count = ::GetLocaleInfo(lcid, LOCALE_SDECIMAL, buffer, 256);
|
if ( ::GetLocaleInfo(lcid, LOCALE_SDECIMAL, buf, WXSIZEOF(buf)) )
|
||||||
if (!count)
|
str = buf;
|
||||||
str << wxS(".");
|
|
||||||
else
|
|
||||||
str << buffer;
|
|
||||||
break;
|
break;
|
||||||
#if 0
|
|
||||||
case wxSYS_LIST_SEPARATOR:
|
case wxLOCALE_SHORT_DATE_FMT:
|
||||||
count = ::GetLocaleInfo(lcid, LOCALE_SLIST, buffer, 256);
|
case wxLOCALE_LONG_DATE_FMT:
|
||||||
if (!count)
|
case wxLOCALE_TIME_FMT:
|
||||||
str << wxS(",");
|
if ( ::GetLocaleInfo(lcid, GetLCTYPEFormatFromLocalInfo(index),
|
||||||
else
|
buf, WXSIZEOF(buf)) )
|
||||||
str << buffer;
|
{
|
||||||
break;
|
return TranslateFromUnicodeFormat(buf);
|
||||||
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;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
wxFAIL_MSG(wxS("Unknown System String !"));
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
default:
|
||||||
|
wxFAIL_MSG( "unknown wxLocaleInfo" );
|
||||||
|
}
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(__DARWIN__)
|
#elif defined(__WXOSX__)
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat))
|
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);
|
cfstr = (CFStringRef) CFLocaleGetValue(userLocaleRef, kCFLocaleDecimalSeparator);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case wxLOCALE_SHORT_DATE_FMT:
|
||||||
|
case wxLOCALE_LONG_DATE_FMT:
|
||||||
|
case wxLOCALE_DATE_TIME_FMT:
|
||||||
|
case wxLOCALE_TIME_FMT:
|
||||||
|
// TODO
|
||||||
|
return wxString();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
wxFAIL_MSG( "Unknown locale info" );
|
wxFAIL_MSG( "Unknown locale info" );
|
||||||
cfstr = CFSTR("");
|
return wxString();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCFStringRef str(wxCFRetain(cfstr));
|
wxCFStringRef str(wxCFRetain(cfstr));
|
||||||
return str.AsString();
|
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 */
|
/* static */
|
||||||
wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat)
|
wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat)
|
||||||
@@ -2693,36 +3007,43 @@ wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat)
|
|||||||
if ( !lc )
|
if ( !lc )
|
||||||
return wxString();
|
return wxString();
|
||||||
|
|
||||||
switch ( cat )
|
|
||||||
{
|
|
||||||
case wxLOCALE_CAT_NUMBER:
|
|
||||||
switch ( index )
|
switch ( index )
|
||||||
{
|
{
|
||||||
case wxLOCALE_THOUSANDS_SEP:
|
case wxLOCALE_THOUSANDS_SEP:
|
||||||
|
if ( cat == wxLOCALE_CAT_NUMBER )
|
||||||
return lc->thousands_sep;
|
return lc->thousands_sep;
|
||||||
|
else if ( cat == wxLOCALE_CAT_MONEY )
|
||||||
case wxLOCALE_DECIMAL_POINT:
|
|
||||||
return lc->decimal_point;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case wxLOCALE_CAT_MONEY:
|
|
||||||
switch ( index )
|
|
||||||
{
|
|
||||||
case wxLOCALE_THOUSANDS_SEP:
|
|
||||||
return lc->mon_thousands_sep;
|
return lc->mon_thousands_sep;
|
||||||
|
|
||||||
case wxLOCALE_DECIMAL_POINT:
|
wxFAIL_MSG( "invalid wxLocaleCategory" );
|
||||||
return lc->mon_decimal_point;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
|
||||||
wxFAIL_MSG( "unknown wxLocaleCategory" );
|
case wxLOCALE_DECIMAL_POINT:
|
||||||
return wxString(); // skip second assert below
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxFAIL_MSG( "unknown wxLocaleInfo value for this category" );
|
return GetDateFormatFromLangInfo(index);
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
wxFAIL_MSG( "unknown wxLocaleInfo value" );
|
||||||
|
}
|
||||||
|
|
||||||
return wxString();
|
return wxString();
|
||||||
}
|
}
|
||||||
|
@@ -691,7 +691,10 @@ void DateTimeTestCase::TestTimeFormat()
|
|||||||
{ 6, wxDateTime::Feb, 1856, 23, 30, 00, 0.0, wxDateTime::Inv_WeekDay },
|
{ 6, wxDateTime::Feb, 1856, 23, 30, 00, 0.0, wxDateTime::Inv_WeekDay },
|
||||||
{ 6, wxDateTime::Feb, 1857, 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::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
|
#if 0
|
||||||
// Need to add support for BCE dates.
|
// Need to add support for BCE dates.
|
||||||
{ 01, wxDateTime::Jan, -52, 03, 16, 47, 0.0, wxDateTime::Inv_WeekDay },
|
{ 01, wxDateTime::Jan, -52, 03, 16, 47, 0.0, wxDateTime::Inv_WeekDay },
|
||||||
@@ -777,6 +780,12 @@ void DateTimeTestCase::TestTimeFormat()
|
|||||||
|
|
||||||
wxDateTime dt;
|
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
|
// test partially specified dates too
|
||||||
wxDateTime dtDef(26, wxDateTime::Sep, 2008);
|
wxDateTime dtDef(26, wxDateTime::Sep, 2008);
|
||||||
CPPUNIT_ASSERT( dt.ParseFormat("17", "%d") );
|
CPPUNIT_ASSERT( dt.ParseFormat("17", "%d") );
|
||||||
|
@@ -41,10 +41,12 @@ private:
|
|||||||
CPPUNIT_TEST_SUITE( IntlTestCase );
|
CPPUNIT_TEST_SUITE( IntlTestCase );
|
||||||
CPPUNIT_TEST( Domain );
|
CPPUNIT_TEST( Domain );
|
||||||
CPPUNIT_TEST( Headers );
|
CPPUNIT_TEST( Headers );
|
||||||
|
CPPUNIT_TEST( DateTimeFmt );
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
void Domain();
|
void Domain();
|
||||||
void Headers();
|
void Headers();
|
||||||
|
void DateTimeFmt();
|
||||||
|
|
||||||
wxLocale *m_locale;
|
wxLocale *m_locale;
|
||||||
|
|
||||||
@@ -59,13 +61,16 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( IntlTestCase, "IntlTestCase" );
|
|||||||
|
|
||||||
void IntlTestCase::setUp()
|
void IntlTestCase::setUp()
|
||||||
{
|
{
|
||||||
if (!wxLocale::IsAvailable(wxLANGUAGE_FRENCH))
|
// Check that French locale is supported, this test doesn't work without it
|
||||||
return; // you should have french support installed to run this test!
|
// 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");
|
wxLocale::AddCatalogLookupPathPrefix("./intl");
|
||||||
|
|
||||||
m_locale = new wxLocale;
|
m_locale = new wxLocale;
|
||||||
CPPUNIT_ASSERT( m_locale);
|
CPPUNIT_ASSERT( m_locale );
|
||||||
|
|
||||||
// don't load default catalog, it may be unavailable:
|
// don't load default catalog, it may be unavailable:
|
||||||
bool loaded = m_locale->Init(wxLANGUAGE_FRENCH, wxLOCALE_CONV_ENCODING);
|
bool loaded = m_locale->Init(wxLANGUAGE_FRENCH, wxLOCALE_CONV_ENCODING);
|
||||||
@@ -86,7 +91,7 @@ void IntlTestCase::tearDown()
|
|||||||
void IntlTestCase::Domain()
|
void IntlTestCase::Domain()
|
||||||
{
|
{
|
||||||
if (!m_locale)
|
if (!m_locale)
|
||||||
return; // no french support installed on this system!
|
return;
|
||||||
|
|
||||||
// _() searches all domains by default:
|
// _() searches all domains by default:
|
||||||
CPPUNIT_ASSERT_EQUAL( "&Ouvrir un fichier", _("&Open bogus file") );
|
CPPUNIT_ASSERT_EQUAL( "&Ouvrir un fichier", _("&Open bogus file") );
|
||||||
@@ -100,8 +105,8 @@ void IntlTestCase::Domain()
|
|||||||
|
|
||||||
void IntlTestCase::Headers()
|
void IntlTestCase::Headers()
|
||||||
{
|
{
|
||||||
if (!m_locale)
|
if ( !m_locale )
|
||||||
return; // no french support installed on this system!
|
return;
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL( "wxWindows 2.0 i18n sample", m_locale->GetHeaderValue("Project-Id-Version") );
|
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") );
|
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") );
|
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
|
#endif // wxUSE_INTL
|
||||||
|
Reference in New Issue
Block a user