The constructors QQmlApplicationEngine and QSettings spoil the time zone (daylight)



  • I came across the strange behavior of the QQmlApplicationEngine constructor. The minimum code is main.cpp:

    #include <QApplication>
    #include <QQmlApplicationEngine>
    #include <QDebug>
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        qDebug() << "1ST timezone=" << timezone << " daylight=" << daylight;
        tzset();
        qDebug() << "2ND timezone=" << timezone << " daylight=" << daylight;
    
        QQmlApplicationEngine engine;
    
        qDebug() << "3ND timezone=" << timezone << " daylight=" << daylight;
    
        return app.exec();
    }
    

    Result of work:

    1ST timezone= 0  daylight= 0
    2ND timezone= -10800  daylight= 1
    3ND timezone= -10800  daylight= 0
    

    That is, after the QQmlApplicationEngine constructor is triggered, daylight spoils (switch to zero).

    I was surprised, but it's necessary to work and therefore I tried to get around this case like this:

    long saveTimezone=timezone;
    int saveDaylight=daylight;
    
    QQmlApplicationEngine engine;
    
    timezone=saveTimezone;
    daylight=saveDaylight;
    

    It worked, but in the project I still found another one place in which the same behavior, after the QSettings constructor (but already in the heap). Looks like that:

    qDebug() << "CURRENT timezone=" << timezone << " daylight=" << daylight;
    QSettings *config=new QSettings(fileName, QSettings::IniFormat, this);
    qDebug() << "CURRENT timezone=" << timezone << " daylight=" << daylight;
    
    CURRENT timezone= -10800  daylight= 1
    CURRENT timezone= -10800  daylight= 0
    

    But in a minimal code, I could not repeat this.

    Where else the variable daylight can spoil, I do not know, but I do not rule out such probabilities. The problem is that my project uses a legacy library that works with daylight, and because of these problems it gives the wrong time.

    Questions: what kind of problem is this, why do some Qt classes spoil daylight, how is this thing guaranteed to work around?

    PS: The project file that would quickly compile a minimal example (only the project file and main.cpp will be required):

    time.pro

    CONFIG+=c++11
    CONFIG+=qml_debug
    QT+=gui
    QT+=core
    QT+=quick
    QT+=widgets
    SOURCES += main.cpp
    DEFINES += QT_DEPRECATED_WARNINGS
    

  • Lifetime Qt Champion

    Hi,

    Intriguing !

    What version of Qt are you using ?
    On what platform ?



  • @SGaist
    Debian Linux Stable 64 bit, Qt 5.10.1 by official site.


  • Qt Champions 2017

    @xintrea said in The constructors QQmlApplicationEngine and QSettings spoil the time zone (daylight):

    Qt 5.10.1 by official site

    You mean downloaded from qt.io, correct? Because debian doesn't provide that in stable, but the current Qt version for the testing flavor is exactly 5.10.1.



  • @kshegunov
    Yes. I use Debian Stable 9 (64-bit) with all updates:

    > lsb_release -a
    No LSB modules are available.
    Distributor ID: Debian
    Description:    Debian GNU/Linux 9.3 (stretch)
    Release:        9.3
    Codename:       stretch
    

    I get Qt from qt.io as file qt-opensource-linux-x64-5.10.1.run.


  • Lifetime Qt Champion

    Do you get the same behaviour if you use Debian's provided version of Qt ?



  • @SGaist

    I not experiment with Qt version.

    But i debug this situation. I set watchpoint to system global variable daylight. This is stack if run constructor QQmlApplicationEngine:

    (gdb) where
    #0  update_vars () at tzset.c:156
    #1  0x00007ffff3c8a569 in __tzset_parse_tz (tz=<optimized out>) at tzset.c:391
    #2  0x00007ffff3c8c27b in __tzfile_compute (timer=<optimized out>, use_localtime=use_localtime@entry=1, 
        leap_correct=leap_correct@entry=0x7fffffffd938, leap_hit=leap_hit@entry=0x7fffffffd934, tp=tp@entry=0x7fffffffd980)
        at tzfile.c:691
    #3  0x00007ffff3c8ac44 in __tz_convert (timer=0x7fffffffd978, use_localtime=1, tp=0x7fffffffd980) at tzset.c:624
    #4  0x00007ffff608230a in ?? () from /opt/qt_5_10_1/5.10.1/gcc_64/lib/libQt5Qml.so.5
    #5  0x00007ffff608afab in ?? () from /opt/qt_5_10_1/5.10.1/gcc_64/lib/libQt5Qml.so.5
    #6  0x00007ffff60692db in QV4::ExecutionEngine::ExecutionEngine(QV4::EvalISelFactory*) ()
       from /opt/qt_5_10_1/5.10.1/gcc_64/lib/libQt5Qml.so.5
    #7  0x00007ffff61c949a in QV8Engine::QV8Engine(QJSEngine*) () from /opt/qt_5_10_1/5.10.1/gcc_64/lib/libQt5Qml.so.5
    #8  0x00007ffff5fffb14 in QJSEngine::QJSEngine(QJSEnginePrivate&, QObject*) ()
       from /opt/qt_5_10_1/5.10.1/gcc_64/lib/libQt5Qml.so.5
    #9  0x00007ffff6127969 in QQmlEngine::QQmlEngine(QQmlEnginePrivate&, QObject*) ()
       from /opt/qt_5_10_1/5.10.1/gcc_64/lib/libQt5Qml.so.5
    #10 0x00007ffff61b44e0 in QQmlApplicationEngine::QQmlApplicationEngine(QObject*) ()
       from /opt/qt_5_10_1/5.10.1/gcc_64/lib/libQt5Qml.so.5
    

    And this is stack if run constructor QSettings:

    (gdb) where
    #0  update_vars () at tzset.c:156
    #1  0x00007ffff3c8a569 in __tzset_parse_tz (tz=<optimized out>) at tzset.c:391
    #2  0x00007ffff3c8c27b in __tzfile_compute (timer=<optimized out>, use_localtime=use_localtime@entry=1, 
        leap_correct=leap_correct@entry=0x7fffffffd3f8, leap_hit=leap_hit@entry=0x7fffffffd3f4, tp=tp@entry=0x7fffffffd4a0)
        at tzfile.c:691
    #3  0x00007ffff3c8ac44 in __tz_convert (timer=0x7fffffffd498, use_localtime=1, tp=0x7fffffffd4a0) at tzset.c:624
    #4  0x00007ffff4dc8709 in QDateTime::setMSecsSinceEpoch(long long) () from /opt/qt_5_10_1/5.10.1/gcc_64/lib/libQt5Core.so.5
    #5  0x00007ffff4dcab4d in QDateTime::fromMSecsSinceEpoch(long long, Qt::TimeSpec, int) ()
       from /opt/qt_5_10_1/5.10.1/gcc_64/lib/libQt5Core.so.5
    #6  0x00007ffff4dcb00d in QDateTime::fromMSecsSinceEpoch(long long) () from /opt/qt_5_10_1/5.10.1/gcc_64/lib/libQt5Core.so.5
    #7  0x00007ffff4e87226 in QFileInfo::fileTime(QFileDevice::FileTime) const ()
       from /opt/qt_5_10_1/5.10.1/gcc_64/lib/libQt5Core.so.5
    #8  0x00007ffff4e8732e in QFileInfo::lastModified() const () from /opt/qt_5_10_1/5.10.1/gcc_64/lib/libQt5Core.so.5
    #9  0x00007ffff4ec90e1 in ?? () from /opt/qt_5_10_1/5.10.1/gcc_64/lib/libQt5Core.so.5
    #10 0x00007ffff4ec98cd in ?? () from /opt/qt_5_10_1/5.10.1/gcc_64/lib/libQt5Core.so.5
    #11 0x00007ffff4eca4b4 in ?? () from /opt/qt_5_10_1/5.10.1/gcc_64/lib/libQt5Core.so.5
    #12 0x00007ffff4eca57f in QSettings::QSettings(QString const&, QSettings::Format, QObject*)
    

    Really, QQmlApplicationEngine and QSettings is change timezone and, therefore, daylight.



  • @SGaist

    And function update_vars() is:

    151 static void                                                                                                              
    152 internal_function                                                                                                        
    153 update_vars (void)                                                                                                       
    154 {                                                                                                                        
    155   __daylight = tz_rules[0].offset != tz_rules[1].offset;                                                                 
    156   __timezone = -tz_rules[0].offset;                                                                                      
    157   __tzname[0] = (char *) tz_rules[0].name;                                                                               
    158   __tzname[1] = (char *) tz_rules[1].name;                                                                               
    159                                                                                                                          
    160   /* Keep __tzname_cur_max up to date.  */                                                                               
    161   size_t len0 = strlen (__tzname[0]);                                                                                    
    162   size_t len1 = strlen (__tzname[1]);                                                                                    
    163   if (len0 > __tzname_cur_max)                                                                                           
    164     __tzname_cur_max = len0;                                                                                             
    165   if (len1 > __tzname_cur_max)                                                                                           
    166     __tzname_cur_max = len1;                                                                                             
    167 }
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.