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

Inconsistent daylight saving time (DST) behaviour between qtdeclarative and qtcore when printing QTime in qml

    XMLWordPrintable

Details

    • iOS/tvOS/watchOS, macOS
    • 21
    • 3f44e0fc5f1d55498ce7fb93a7841198a7583a08 (qt/qtdeclarative/5.14)
    • Foundation PM Staging

    Description

      The problem

      When formatting a QTime object in QML, the hour is wrong (due to DST inconsistencies):

      // main.cpp
      ...
      QQmlEngine *pQmlEngine = new QQmlEngine;
      pQmlEngine->rootContext()->setContextProperty("myCESTDate", QTime(18,0));
      ...
      
      // main.qml
      ...
      console.log(myCESTDate); // prints "Mon Jun 8 17:00:00 1925 GMT+0200"
      ...
      

      The reason

      When converting a QTime object from C++ to qml daylight saving time (DST) is determined using localtime_r (call hierarchy: Heap::DateObject::initUTCDaylightSavingTA), which returns DST is true.

      However, the qml (js) Date object is converted back to a QDateTime object using QDateTime::toTimeSpec, which internally calls epochMSecsToLocalTime, which does never sets DST for dates before 1970-01-01:

      static bool epochMSecsToLocalTime(qint64 msecs, QDate *localDate, QTime *localTime,
                                        QDateTimePrivate::DaylightStatus *daylightStatus = 0)
      {
          if (msecs < 0) {
              // Docs state any LocalTime before 1970-01-01 will *not* have any Daylight Time applied
              // Instead just use the standard offset from UTC to convert to UTC time
              qt_tzset();
              msecsToTime(msecs - qt_timezone() * 1000, localDate, localTime);
              if (daylightStatus)
                  *daylightStatus = QDateTimePrivate::StandardTime;
              return true;
          } 
          ...
      }
      

       On Windows, this does not seem to be a problem, but on macOS and iOS the above (wrong) behaviour is observed.

      The solution

      A solution may be to choose a date after 1970-01-01 (instead of 1925-6-8) when converting a QTime object to a qml (js) Date object (see function Heap::DateObject::init, including the implementation comment inside this function). 

      Work around

      A work around (without changing Qt's source code) would be to explicitly specify a (random or current) date after 1970-01-01, when passing a QTime object to qml:

      ...
      pQmlEngine->rootContext()->setContextProperty("myCESTDate", QDateTime(QDate::currentDate(), QTime(18,0)));
      ...
      

      Attachments

        Issue Links

          For Gerrit Dashboard: QTBUG-78706
          # Subject Branch Project Status CR V

          Activity

            People

              Eddy Edward Welbourne
              m3197d - -
              Vladimir Minenko Vladimir Minenko
              Alex Blasche Alex Blasche
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews

                  There are no open Gerrit changes