summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qlocale_mac.mm
diff options
context:
space:
mode:
authorJohn Layt <jlayt@kde.org>2013-09-18 15:53:18 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-26 20:42:33 +0200
commit77dc33dcdbe0eec8ddc9059c4e0ff9dde264c5fa (patch)
treee20772b1cfa847f477cd946dc92fff178dcf656e /src/corelib/tools/qlocale_mac.mm
parent279db88c39ae51db2cde80559e30e52457536d12 (diff)
QLocale - Fix Mac date format code translation
Mac uses the CLDR format codes which need to be translated into their Qt equivalent. The existing code mistranslates the year code, is outdated for a number of new codes introduced in recent versions of CLDR, and by default accepted any codes it didn't recognize. This change updates support to the latest version of CLDR, fixes the treatment of years, and defaults to ignoring any new format codes added in the future. Note that this change cannot have auto tests written as the system locale formats change between versions of OSX. Testing must be done manually by changing system locale and formats. Task-number: QTBUG-25057 Change-Id: I69dda25b4a0b38d3971995644546306876922d57 Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
Diffstat (limited to 'src/corelib/tools/qlocale_mac.mm')
-rw-r--r--src/corelib/tools/qlocale_mac.mm105
1 files changed, 76 insertions, 29 deletions
diff --git a/src/corelib/tools/qlocale_mac.mm b/src/corelib/tools/qlocale_mac.mm
index 43a0d67e74..deb5d5eb1d 100644
--- a/src/corelib/tools/qlocale_mac.mm
+++ b/src/corelib/tools/qlocale_mac.mm
@@ -166,6 +166,11 @@ static QString macTimeToString(const QTime &time, bool short_format)
return QCFString(CFDateFormatterCreateStringWithDate(0, myFormatter, myDate));
}
+// Mac uses the Unicode CLDR format codes
+// http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
+// See also qtbase/util/local_database/dateconverter.py
+// Makes the assumption that input formats are always well formed and consecutive letters
+// never exceed the maximum for the format code.
static QString macToQtFormat(const QString &sys_fmt)
{
QString result;
@@ -185,55 +190,97 @@ static QString macToQtFormat(const QString &sys_fmt)
int repeat = qt_repeatCount(sys_fmt, i);
switch (c.unicode()) {
- case 'G': // Qt doesn't support these :(
- case 'Y':
- case 'D':
- case 'F':
- case 'w':
- case 'W':
- case 'g':
+ // Qt does not support the following options
+ case 'G': // Era (1..5): 4 = long, 1..3 = short, 5 = narrow
+ case 'Y': // Year of Week (1..n): 1..n = padded number
+ case 'U': // Cyclic Yar Name (1..5): 4 = long, 1..3 = short, 5 = narrow
+ case 'Q': // Quarter (1..4): 4 = long, 3 = short, 1..2 = padded number
+ case 'q': // Standalone Quarter (1..4): 4 = long, 3 = short, 1..2 = padded number
+ case 'w': // Week of Year (1..2): 1..2 = padded number
+ case 'W': // Week of Month (1): 1 = number
+ case 'D': // Day of Year (1..3): 1..3 = padded number
+ case 'F': // Day of Week in Month (1): 1 = number
+ case 'g': // Modified Julian Day (1..n): 1..n = padded number
+ case 'A': // Milliseconds in Day (1..n): 1..n = padded number
break;
- case 'u': // extended year - use 'y'
- if (repeat < 4)
+ case 'y': // Year (1..n): 2 = short year, 1 & 3..n = padded number
+ case 'u': // Extended Year (1..n): 2 = short year, 1 & 3..n = padded number
+ // Qt only supports long (4) or short (2) year, use long for all others
+ if (repeat == 2)
result += QLatin1String("yy");
else
result += QLatin1String("yyyy");
break;
- case 'S': // fractional second
- if (repeat < 3)
- result += QLatin1Char('z');
+ case 'M': // Month (1..5): 4 = long, 3 = short, 1..2 = number, 5 = narrow
+ case 'L': // Standalone Month (1..5): 4 = long, 3 = short, 1..2 = number, 5 = narrow
+ // Qt only supports long, short and number, use short for narrow
+ if (repeat == 5)
+ result += QLatin1String("MMM");
else
- result += QLatin1String("zzz");
+ result += QString(repeat, QLatin1Char('M'));
break;
- case 'E':
- if (repeat <= 3)
- result += QLatin1String("ddd");
- else
+ case 'd': // Day of Month (1..2): 1..2 padded number
+ result += QString(repeat, c);
+ break;
+ case 'E': // Day of Week (1..6): 4 = long, 1..3 = short, 5..6 = narrow
+ // Qt only supports long, short and padded number, use short for narrow
+ if (repeat == 4)
result += QLatin1String("dddd");
+ else
+ result += QLatin1String("ddd");
break;
- case 'e':
- if (repeat >= 2)
- result += QLatin1String("dd");
+ case 'e': // Local Day of Week (1..6): 4 = long, 3 = short, 5..6 = narrow, 1..2 padded number
+ case 'c': // Standalone Local Day of Week (1..6): 4 = long, 3 = short, 5..6 = narrow, 1..2 padded number
+ // Qt only supports long, short and padded number, use short for narrow
+ if (repeat >= 5)
+ result += QLatin1String("ddd");
else
- result += QLatin1Char('d');
+ result += QString(repeat, QLatin1Char('d'));
break;
- case 'a':
+ case 'a': // AM/PM (1): 1 = short
+ // Translate to Qt uppercase AM/PM
result += QLatin1String("AP");
break;
- case 'k':
+ case 'h': // Hour [1..12] (1..2): 1..2 = padded number
+ case 'K': // Hour [0..11] (1..2): 1..2 = padded number
+ case 'j': // Local Hour [12 or 24] (1..2): 1..2 = padded number
+ // Qt h is local hour
+ result += QString(repeat, QLatin1Char('h'));
+ break;
+ case 'H': // Hour [0..23] (1..2): 1..2 = padded number
+ case 'k': // Hour [1..24] (1..2): 1..2 = padded number
+ // Qt H is 0..23 hour
result += QString(repeat, QLatin1Char('H'));
break;
- case 'K':
- result += QString(repeat, QLatin1Char('h'));
+ case 'm': // Minutes (1..2): 1..2 = padded number
+ case 's': // Seconds (1..2): 1..2 = padded number
+ result += QString(repeat, c);
+ break;
+ case 'S': // Fractional second (1..n): 1..n = tuncates to decimal places
+ // Qt uses msecs either unpadded or padded to 3 places
+ if (repeat < 3)
+ result += QLatin1Char('z');
+ else
+ result += QLatin1String("zzz");
break;
- case 'z':
- case 'Z':
- case 'v':
+ case 'z': // Time Zone (1..4)
+ case 'Z': // Time Zone (1..5)
+ case 'O': // Time Zone (1, 4)
+ case 'v': // Time Zone (1, 4)
+ case 'V': // Time Zone (1..4)
+ case 'X': // Time Zone (1..5)
+ case 'x': // Time Zone (1..5)
result += QLatin1Char('t');
break;
default:
- result += QString(repeat, c);
+ // a..z and A..Z are reserved for format codes, so any occurrence of these not
+ // already processed are not known and so unsupported formats to be ignored.
+ // All other chars are allowed as literals.
+ if (c < QLatin1Char('A') || c > QLatin1Char('z') ||
+ (c > QLatin1Char('Z') && c < QLatin1Char('a'))) {
+ result += QString(repeat, c);
+ }
break;
}