Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-55151

Cannot change times in QDateTimeEdit if format includes AM/PM and widget locale != translator language

    XMLWordPrintable

Details

    • Bug
    • Resolution: Cannot Reproduce
    • P3: Somewhat important
    • 5.6.3
    • 5.4.0, 5.5.0
    • None
    • Windows, though I don't think that really matters

    Description

      If you set the format on a QDateTimeEdit that includes "a" or "AP" (the markers to include AM/PM) and the locale of the widget does not match any installed translators then you won't be able to change the time.

      The underlying issue is that QDateTimeEdit uses two different systems for displaying vs parsing the strings it displays. QDateTimeEdit delegates the responsibility of generating the text to display to its QLocale (QLocalePrivate::dateTimeToString has the interesting bits). QLocale generates these by using a hardcoded set of hex values which it coerces into a string (see qlocale_data_p.h for arrays and getLocaleData in qlocale.cpp).

      However when parsing, QDateTimeEdit uses QWidget::tr to translate AM/PM to the UI locale's language (QDateTimeParser::findAmPm). This means if they don't match then, even if you only change a number, the widget won't recognize the AM/PM text it just displayed and will fail to validate it, causing it to revert to the original text. It gets worse - the only translations for AM/PM are in the korean text file (for some reason) so even if you have a Chinese language AND locale it still won't parse.

      I was able to repro this with some simple code (full project attached)

          ui->dateTimeEdit->setLocale(QLocale("ko_KR"));
          ui->dateTimeEdit->setDisplayFormat("M/d/yyyy h:mm:ss a");
          ui->dateTimeEdit->setDateTime(QDateTime(QDate(2012, 1, 1), QTime(12, 35, 00)));
      

      Run the app and notice you can't change the time...

      We're probably going to fix this locally by updating the QDateTimeEditPrivate::amPMText to use its locale instead of the translator.

      QString QDateTimeEditPrivate::getAmPmText(AmPm ap, Case cs) const
      {
          QString txt = ap == AmText ? locale().amText() : locale().pmText();
          return cs == UpperCase ? txt.toUpper() : txt.toLower();
      }
      

      Btw, for versions I did 5.4 and 5.5 because those are the versions I tested this with but from browsing the source of later versions online this doesn't appear to be fixed (though it was edited for this bug: https://bugreports.qt.io/browse/QTBUG-251)

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              qt.team.quick.subscriptions Qt Quick and Widgets Team
              wmartin Will Martin
              Votes:
              1 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes