13#include "QtCore/private/qgregoriancalendar_p.h"
21#if QT_CONFIG(cpp_winrt)
22# include <QtCore/private/qt_winrtbase_p.h>
24# include <winrt/Windows.Foundation.h>
25# include <winrt/Windows.Foundation.Collections.h>
26# include <winrt/Windows.System.UserProfile.h>
45 if (used > 0 &&
id && INT_MIN <=
id &&
id <= INT_MAX)
58 if (!
name.isEmpty()) {
59 LCID
id = LocaleNameToLCID(
static_cast<LPCWSTR
>(
65 return GetUserDefaultLCID();
70#ifndef QT_NO_SYSTEMLOCALE
72#ifndef MUI_LANGUAGE_NAME
73#define MUI_LANGUAGE_NAME 0x8
75#ifndef LOCALE_SSHORTESTDAYNAME1
76# define LOCALE_SSHORTESTDAYNAME1 0x0060
77# define LOCALE_SSHORTESTDAYNAME2 0x0061
78# define LOCALE_SSHORTESTDAYNAME3 0x0062
79# define LOCALE_SSHORTESTDAYNAME4 0x0063
80# define LOCALE_SSHORTESTDAYNAME5 0x0064
81# define LOCALE_SSHORTESTDAYNAME6 0x0065
82# define LOCALE_SSHORTESTDAYNAME7 0x0066
84#ifndef LOCALE_SNATIVELANGUAGENAME
85# define LOCALE_SNATIVELANGUAGENAME 0x00000004
87#ifndef LOCALE_SNATIVECOUNTRYNAME
88# define LOCALE_SNATIVECOUNTRYNAME 0x00000008
90#ifndef LOCALE_SSHORTTIME
91# define LOCALE_SSHORTTIME 0x00000079
101 return std::move(
value);
137 enum SubstitutionType {
146 SubstitutionType substitutionType = SUnknown;
151 int getLocaleInfo_int(LCTYPE
type);
157 SubstitutionType substitution();
172inline int QSystemLocalePrivate::getCurrencyFormat(DWORD
flags, LPCWSTR
value,
const CURRENCYFMTW *
format, LPWSTR
data,
int size)
177inline int QSystemLocalePrivate::getDateFormat(DWORD
flags,
const SYSTEMTIME *
date, LPCWSTR
format, LPWSTR
data,
int size)
182inline int QSystemLocalePrivate::getTimeFormat(DWORD
flags,
const SYSTEMTIME *
date, LPCWSTR
format, LPWSTR
data,
int size)
187inline int QSystemLocalePrivate::getLocaleInfo(LCTYPE
type, LPWSTR
data,
int size)
192QVariant QSystemLocalePrivate::getLocaleInfo(LCTYPE
type)
199 QVarLengthArray<wchar_t, 64>
buf(64);
201 if (!getLocaleInfo(
type,
buf.data(),
buf.size())) {
202 const auto lastError = GetLastError();
203 if (
type == LOCALE_SPOSITIVESIGN && lastError == ERROR_SUCCESS)
205 if (lastError != ERROR_INSUFFICIENT_BUFFER)
207 int cnt = getLocaleInfo(
type, 0, 0);
211 if (!getLocaleInfo(
type,
buf.data(),
buf.size()))
214 if (
type == LOCALE_SPOSITIVESIGN && !
buf[0])
219int QSystemLocalePrivate::getLocaleInfo_int(LCTYPE
type)
222 int r = GetLocaleInfo(lcid,
type | LOCALE_RETURN_NUMBER,
223 reinterpret_cast<wchar_t *
>(&
value),
224 sizeof(
value) /
sizeof(
wchar_t));
225 return r ==
sizeof(
value) /
sizeof(
wchar_t) ?
value : 0;
228QSystemLocalePrivate::SubstitutionType QSystemLocalePrivate::substitution()
230 if (substitutionType == SUnknown) {
232 if (!getLocaleInfo(LOCALE_IDIGITSUBSTITUTION,
buf, 8)) {
233 substitutionType = SNever;
234 return substitutionType;
237 substitutionType = SNever;
238 else if (
buf[0] ==
'0')
239 substitutionType = SContext;
240 else if (
buf[0] ==
'2')
241 substitutionType = SAlways;
244 if (!getLocaleInfo(LOCALE_SNATIVEDIGITS,
digits, 11)) {
245 substitutionType = SNever;
246 return substitutionType;
249 substitutionType = SAlways;
251 substitutionType = SNever;
254 return substitutionType;
260 switch (zero.
size()) {
266 ushort *
const qch =
reinterpret_cast<ushort *
>(
string.data());
269 if (
ch >=
'0' &&
ch <=
'9')
276 char32_t z = QChar::surrogateToUcs4(zero.
at(0), zero.
at(1));
277 for (
int i = 0;
i < 10;
i++) {
279 const QChar s[2] = { QChar::highSurrogate(digit), QChar::lowSurrogate(digit) };
285 Q_ASSERT(!
"Expected zero digit to be a single UCS2 code-point or a surrogate pair");
289 return std::move(
string);
294 return substitution() == SAlways ? substituteDigits(std::move(
string)) :
std::move(
string);
308 if (getLocaleInfo(LOCALE_SNATIVEDIGITS,
digits, 11)) {
314 return nullIfEmpty(zero);
319 return nullIfEmpty(getLocaleInfo(LOCALE_SDECIMAL).
toString());
324 return getLocaleInfo(LOCALE_STHOUSAND);
329 return nullIfEmpty(getLocaleInfo(LOCALE_SNEGATIVESIGN).
toString());
334 return nullIfEmpty(getLocaleInfo(LOCALE_SPOSITIVESIGN).
toString());
341 return nullIfEmpty(winToQtFormat(getLocaleInfo(LOCALE_SSHORTDATE).
toString()));
343 return nullIfEmpty(winToQtFormat(getLocaleInfo(LOCALE_SLONGDATE).
toString()));
356 return nullIfEmpty(winToQtFormat(getLocaleInfo(LOCALE_STIMEFORMAT).
toString()));
366 if (
d.typeId() == QMetaType::QString &&
t.typeId() == QMetaType::QString)
367 return QString(
d.toString() + u
' ' +
t.toString());
373 if (day < 1 || day > 7)
376 static constexpr LCTYPE short_day_map[]
377 = { LOCALE_SABBREVDAYNAME1, LOCALE_SABBREVDAYNAME2,
378 LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4, LOCALE_SABBREVDAYNAME5,
379 LOCALE_SABBREVDAYNAME6, LOCALE_SABBREVDAYNAME7 };
381 static constexpr LCTYPE long_day_map[]
382 = { LOCALE_SDAYNAME1, LOCALE_SDAYNAME2,
383 LOCALE_SDAYNAME3, LOCALE_SDAYNAME4, LOCALE_SDAYNAME5,
384 LOCALE_SDAYNAME6, LOCALE_SDAYNAME7 };
386 static constexpr LCTYPE narrow_day_map[]
392 return nullIfEmpty(getLocaleInfo(
395 : short_day_map)[day - 1]).toString());
400 static constexpr LCTYPE short_month_map[]
401 = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2, LOCALE_SABBREVMONTHNAME3,
402 LOCALE_SABBREVMONTHNAME4, LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6,
403 LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8, LOCALE_SABBREVMONTHNAME9,
404 LOCALE_SABBREVMONTHNAME10, LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 };
406 static constexpr LCTYPE long_month_map[]
407 = { LOCALE_SMONTHNAME1, LOCALE_SMONTHNAME2, LOCALE_SMONTHNAME3,
408 LOCALE_SMONTHNAME4, LOCALE_SMONTHNAME5, LOCALE_SMONTHNAME6,
409 LOCALE_SMONTHNAME7, LOCALE_SMONTHNAME8, LOCALE_SMONTHNAME9,
410 LOCALE_SMONTHNAME10, LOCALE_SMONTHNAME11, LOCALE_SMONTHNAME12 };
412 if (month < 1 || month > 12)
416 return nullIfEmpty(getLocaleInfo(
447QString QSystemLocalePrivate::yearFix(
int year,
int fakeYear,
QString &&formatted)
452 Q_ASSERT(fakeYear >= 1970 && fakeYear <= 2400);
453 const bool matchTwo = year >= 0 && year % 100 == fakeYear % 100;
457 if (formatted.contains(yearUsed))
458 return std::move(formatted).replace(yearUsed,
sign + trueYear);
462 if (formatted.contains(tail)) {
464 return std::move(formatted);
465 return std::move(formatted).replace(tail.toString(),
sign + trueYear.last(2));
470 trueYear = substituteDigits(std::move(trueYear));
472 yearUsed = substituteDigits(std::move(yearUsed));
476 if (formatted.contains(yearUsed))
477 return std::move(formatted).
replace(yearUsed,
sign + trueYear);
481 if (formatted.contains(tail)) {
483 return std::move(formatted);
484 return std::move(formatted).replace(tail.toString(),
sign + trueYear.last(twoDigits));
487 qWarning(
"Failed to fix up year in formatted date-string using %d for %d", fakeYear, year);
488 return std::move(formatted);
497 const bool fixup = year < 1601;
502 Q_ASSERT(!fixup || st.wYear % 100 != st.wMonth);
503 Q_ASSERT(!fixup || st.wYear % 100 != st.wDay);
509 if (getDateFormat(
flags, &st, NULL,
buf, 255)) {
512 text = yearFix(year, st.wYear, std::move(
text));
513 return nullIfEmpty(correctDigits(std::move(
text)));
524 st.wMilliseconds = 0;
531 auto formatStr =
reinterpret_cast<const wchar_t *
>(
format.isEmpty() ?
nullptr :
format.utf16());
534 if (getTimeFormat(
flags, &st, formatStr,
buf,
int(std::size(
buf))))
542 if (
d.typeId() == QMetaType::QString &&
t.typeId() == QMetaType::QString)
543 return QString(
d.toString() + u
' ' +
t.toString());
551 if (getLocaleInfo(LOCALE_IMEASURE,
output, 2)) {
561 return getLocaleInfo(LOCALE_SSORTLOCALE);
568 if (getLocaleInfo(LOCALE_S1159,
output, 15))
578 if (getLocaleInfo(LOCALE_S2359,
output, 15))
588 if (getLocaleInfo(LOCALE_IFIRSTDAYOFWEEK,
output, 4))
601 if (getLocaleInfo(LOCALE_SCURRENCY,
buf, 13))
605 if (getLocaleInfo(LOCALE_SINTLSYMBOL,
buf, 9))
609 QVarLengthArray<wchar_t, 64>
buf(64);
610 if (!getLocaleInfo(LOCALE_SNATIVECURRNAME,
buf.data(),
buf.size())) {
611 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
614 if (!getLocaleInfo(LOCALE_SNATIVECURRNAME,
buf.data(),
buf.size()))
628 switch (
arg.value.typeId()) {
633 case QMetaType::UInt:
637 case QMetaType::Double:
641 case QMetaType::LongLong:
645 case QMetaType::ULongLong:
653 QVarLengthArray<wchar_t, 64>
out(64);
658 CURRENCYFMT *pformat = NULL;
659 if (!
arg.symbol.isEmpty()) {
660 format.NumDigits = getLocaleInfo_int(LOCALE_ICURRDIGITS);
661 format.LeadingZero = getLocaleInfo_int(LOCALE_ILZERO);
662 decimalSep = getLocaleInfo(LOCALE_SMONDECIMALSEP).toString();
663 format.lpDecimalSep = (
wchar_t *)decimalSep.utf16();
664 thousandSep = getLocaleInfo(LOCALE_SMONTHOUSANDSEP).toString();
665 format.lpThousandSep = (
wchar_t *)thousandSep.utf16();
666 format.NegativeOrder = getLocaleInfo_int(LOCALE_INEGCURR);
667 format.PositiveOrder = getLocaleInfo_int(LOCALE_ICURRENCY);
668 format.lpCurrencySymbol = (
wchar_t *)
arg.symbol.utf16();
676 QString groupingStr = getLocaleInfo(LOCALE_SMONGROUPING).toString();
677 format.Grouping = groupingStr.remove(u
';').toInt();
678 if (
format.Grouping % 10 == 0)
685 int ret = getCurrencyFormat(0,
reinterpret_cast<const wchar_t *
>(
value.utf16()),
686 pformat,
out.data(),
out.size());
687 if (
ret == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
688 ret = getCurrencyFormat(0,
reinterpret_cast<const wchar_t *
>(
value.utf16()),
689 pformat,
out.data(), 0);
691 getCurrencyFormat(0,
reinterpret_cast<const wchar_t *
>(
value.utf16()),
692 pformat,
out.data(),
out.size());
701#if QT_CONFIG(cpp_winrt)
702 using namespace winrt;
703 using namespace Windows::System::UserProfile;
705 auto languages = GlobalizationPreferences::Languages();
706 for (
const auto &lang : languages)
715 unsigned long cnt = 0;
716 QVarLengthArray<wchar_t, 64>
buf(64);
717# if !defined(QT_BOOTSTRAPPED)
718 unsigned long size =
buf.size();
721 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER &&
731 for (; cnt > 0; --cnt) {
738 return nullIfEmpty(std::move(
result));
755 substitutionType = SUnknown;
764 while (
i < sys_fmt.size()) {
765 if (sys_fmt.at(
i).unicode() == u
'\'') {
777 switch (
c.unicode()) {
782 else if (repeat == 3)
833 return d->decimalPoint();
835 return d->groupSeparator();
837 return d->negativeSign();
839 return d->positiveSign();
888 return d->zeroDigit();
894 return lid.language_id;
900 return d->measurementSystem();
902 return d->collation();
908 return d->firstDayOfWeek();
912 return d->toCurrencyString(
in.value<CurrencyToStringArgument>());
914 return d->uiLanguages();
919 return d->nativeLanguageName();
921 return d->nativeTerritoryName();
935struct ByWindowsCode {
939 {
return int(lhs.windows_code) < rhs; }
1000 { 0x0814,
"no\0 " },
1001 { 0x0816,
"pt\0 " },
1002 { 0x081a,
"sr\0 " },
1003 { 0x081d,
"sv_FI" },
1004 { 0x0c01,
"ar_EG" },
1005 { 0x0c04,
"zh_HK" },
1006 { 0x0c07,
"de_AT" },
1007 { 0x0c09,
"en_AU" },
1008 { 0x0c0a,
"es\0 " },
1009 { 0x0c0c,
"fr_CA" },
1010 { 0x0c1a,
"sr\0 " },
1011 { 0x1001,
"ar_LY" },
1012 { 0x1004,
"zh_SG" },
1013 { 0x1007,
"de_LU" },
1014 { 0x1009,
"en_CA" },
1015 { 0x100a,
"es_GT" },
1016 { 0x100c,
"fr_CH" },
1017 { 0x1401,
"ar_DZ" },
1018 { 0x1407,
"de_LI" },
1019 { 0x1409,
"en_NZ" },
1020 { 0x140a,
"es_CR" },
1021 { 0x140c,
"fr_LU" },
1022 { 0x1801,
"ar_MA" },
1023 { 0x1809,
"en_IE" },
1024 { 0x180a,
"es_PA" },
1025 { 0x1c01,
"ar_TN" },
1026 { 0x1c09,
"en_ZA" },
1027 { 0x1c0a,
"es_DO" },
1028 { 0x2001,
"ar_OM" },
1029 { 0x2009,
"en_JM" },
1030 { 0x200a,
"es_VE" },
1031 { 0x2401,
"ar_YE" },
1032 { 0x2409,
"en\0 " },
1033 { 0x240a,
"es_CO" },
1034 { 0x2801,
"ar_SY" },
1035 { 0x2809,
"en_BZ" },
1036 { 0x280a,
"es_PE" },
1037 { 0x2c01,
"ar_JO" },
1038 { 0x2c09,
"en_TT" },
1039 { 0x2c0a,
"es_AR" },
1040 { 0x3001,
"ar_LB" },
1041 { 0x300a,
"es_EC" },
1042 { 0x3401,
"ar_KW" },
1043 { 0x340a,
"es_CL" },
1044 { 0x3801,
"ar_AE" },
1045 { 0x380a,
"es_UY" },
1046 { 0x3c01,
"ar_BH" },
1047 { 0x3c0a,
"es_PY" },
1048 { 0x4001,
"ar_QA" },
1049 { 0x400a,
"es_BO" },
1050 { 0x440a,
"es_SV" },
1051 { 0x480a,
"es_HN" },
1052 { 0x4c0a,
"es_NI" },
1073 return it->iso_name;
1082 return LOCALE_USER_DEFAULT;
1084 if (!strncmp(
name,
"nb", 2))
1086 if (!strncmp(
name,
"nn", 2))
1090 strncpy(
n,
name,
sizeof(
n));
1100 if (!strcmp(
n,
i.iso_name))
1101 return i.windows_code;
1103 return LOCALE_USER_DEFAULT;
1115 if (GetLocaleInfo(
id, LOCALE_ILANGUAGE,
out, 255))
1118 if (!lang_code.isEmpty()) {
1119 const QByteArray latin1 = std::move(lang_code).toLatin1();
1121 if (used >= latin1.
size() || (used > 0 && latin1[used] ==
'\0')) {
1136 if (GetLocaleInfo(
id, LOCALE_SISO639LANGNAME,
out, 255))
1147 if (GetLocaleInfo(
id, LOCALE_SISO3166CTRYNAME,
out, 255))
1156 if (
id == LOCALE_USER_DEFAULT) {
1158 if (!
name.isEmpty())
1163 id = GetUserDefaultLCID();
1169 resultusage += u
'_' + country;
1171 return std::move(resultusage).
toLatin1();
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
\inmodule QtCore\reentrant
\inmodule QtCore \reentrant
int month() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
int day() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
int year() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
static int yearSharingWeekDays(QDate date)
constexpr QStringView last(qsizetype n) const noexcept
\macro QT_RESTRICTED_CAST_FROM_ASCII
QByteArray toLatin1() const &
QString & replace(qsizetype i, qsizetype len, QChar after)
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QString fromStdString(const std::string &s)
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
const QChar * constData() const
Returns a pointer to the data stored in the QString.
qsizetype size() const noexcept
Returns the number of characters in this string.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
void resize(qsizetype size)
Sets the size of the string to size characters.
@ StandaloneMonthNameLong
@ StandaloneDayNameNarrow
@ StandaloneMonthNameNarrow
@ StandaloneMonthNameShort
virtual QLocale fallbackLocale() const
virtual QVariant query(QueryType type, QVariant &&in=QVariant()) const
\inmodule QtCore \reentrant
int hour() const
Returns the hour part (0 to 23) of the time.
int minute() const
Returns the minute part (0 to 59) of the time.
int second() const
Returns the second part (0 to 59) of the time.
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
QSet< QString >::iterator it
Combined button and popup list for selecting options.
constexpr bool is_sorted(ForwardIterator first, ForwardIterator last, BinaryPredicate p={})
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
qsizetype qt_repeatCount(QStringView s)
bool qt_splitLocaleName(QStringView name, QStringView *lang, QStringView *script, QStringView *land)
QString qt_readEscapedFormatString(QStringView format, qsizetype *idx)
static QByteArray getWinLocaleName(LCID id=LOCALE_USER_DEFAULT)
static QString fourDigitYear(int year)
#define LOCALE_SSHORTESTDAYNAME2
static auto scanLangEnv()
#define LOCALE_SSHORTTIME
#define LOCALE_SSHORTESTDAYNAME4
#define LOCALE_SSHORTESTDAYNAME3
#define LOCALE_SSHORTESTDAYNAME7
static constexpr WindowsToISOListElt windows_to_iso_list[]
#define LOCALE_SSHORTESTDAYNAME5
#define LOCALE_SNATIVELANGUAGENAME
Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id)
static QString winIso3116CtryName(LCID id)
#define LOCALE_SSHORTESTDAYNAME6
#define LOCALE_SNATIVECOUNTRYNAME
static auto getDefaultWinId()
#define MUI_LANGUAGE_NAME
LCID qt_inIsoNametoLCID(const char *name)
static const char * winLangCodeToIsoName(int code)
#define LOCALE_SSHORTESTDAYNAME1
static QString winIso639LangName(LCID id)
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLsizei GLsizei GLenum format
GLsizei const GLchar *const * string
[0]
#define QStringLiteral(str)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
QT_BEGIN_NAMESPACE typedef uchar * output
QTextStream out(stdout)
[7]
\inmodule QtCore \reentrant
static const QLocaleData * c()
static Q_AUTOTEST_EXPORT QLocaleId fromName(QStringView name)
QVariant dateFormat(QLocale::FormatType)
QVariant toString(QDate, QLocale::FormatType)
QVariant dayName(int, QLocale::FormatType)
QVariant firstDayOfWeek()
QVariant monthName(int, QLocale::FormatType)
QVariant currencySymbol(QLocale::CurrencySymbolFormat)
QVariant nativeLanguageName()
QVariant standaloneMonthName(int, QLocale::FormatType)
QVariant nativeTerritoryName()
QVariant dateTimeFormat(QLocale::FormatType)
QVariant measurementSystem()
QVariant groupSeparator()
QVariant timeFormat(QLocale::FormatType)
QVariant toCurrencyString(const QSystemLocale::CurrencyToStringArgument &)