From 8c8b4b8fde83814d542bc50696dafbd5f7278cd7 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 12 Sep 2018 12:41:23 +0200 Subject: Correct and expand support for CLDR's date/time format strings Our conversion from CLDR's format to our own was missing some things it could support sensibly, and some it could do better than ignore or treat as literal, while mis-handling the 'E'-based formats for day names. At least in CLDR v34 this doesn't actually make any difference (on regenerating our locale data, the only change is the date of generation). Task-number: QTBUG-70516 Change-Id: I9d27b9bf24afd168c2f8a5258143d3d695bca0ad Reviewed-by: Thiago Macieira Reviewed-by: Konstantin Ritt --- util/local_database/localexml.py | 48 ++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/util/local_database/localexml.py b/util/local_database/localexml.py index a47fa6a5ff..e95b3aebcc 100644 --- a/util/local_database/localexml.py +++ b/util/local_database/localexml.py @@ -53,7 +53,21 @@ def ordStr(c): def fixOrdStr(c, d): return str(ord(c if len(c) == 1 else d)) +def startCount(c, text): # strspn + """First index in text where it doesn't have a character in c""" + assert text and text[0] in c + try: + return (j for j, d in enumerate(text) if d not in c).next() + except StopIteration: + return len(text) + def convertFormat(format): + """Convert date/time format-specier from CLDR to Qt + + Match up (as best we can) the differences between: + * https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table + * QDateTimeParser::parseFormat() and QLocalePrivate::dateTimeToString() + """ result = "" i = 0 while i < len(format): @@ -68,20 +82,30 @@ def convertFormat(format): i += 1 else: s = format[i:] - if s.startswith("EEEE"): - result += "dddd" - i += 4 - elif s.startswith("EEE"): - result += "ddd" - i += 3 - elif s.startswith("a"): + if s.startswith('E'): # week-day + n = startCount('E', s) + if n < 3: + result += 'ddd' + elif n == 4: + result += 'dddd' + else: # 5: narrow, 6 short; but should be name, not number :-( + result += 'd' if n < 6 else 'dd' + i += n + elif s[0] in 'ab': # am/pm + # 'b' should distinguish noon/midnight, too :-( result += "AP" - i += 1 - elif s.startswith("z"): + i += startCount('ab', s) + elif s.startswith('S'): # fractions of seconds: count('S') == number of decimals to show + result += 'z' + i += startCount('S', s) + elif s.startswith('V'): # long time zone specifiers (and a deprecated short ID) + result += 't' + i += startCount('V', s) + elif s[0] in 'zv': # zone + # Should use full name, e.g. "Central European Time", if 'zzzz' :-( + # 'v' should get generic non-location format, e.g. PT for "Pacific Time", no DST indicator result += "t" - i += 1 - elif s.startswith("v"): - i += 1 + i += startCount('zv', s) else: result += format[i] i += 1 -- cgit v1.2.3