What's New In Qt 5.2: QTimeZone

What's New In Qt 5.2: QTimeZone

Wednesday, March 26, 2014

In this post, I will briefly describe a new class, QTimeZone (1), one of several that were introduced in Qt 5.2, and show an example application that uses it.

Introduction

The QTimeZone class provides detailed information about world time zones, including how to convert between Coordinated Universal Time (UTC), the primary time standard by which the world regulates clocks and time, and local time for a specific time zone, with the details of daylight savings time changes as well.

Most applications that work with times and dates will generally find it sufficient to use the Qt QDate, QTime and QDateTime classes. However, if you need more detailed time zone information, the QTimeZone class will allow you to do this in a platform-independent manner.

The class can return a list of available time zones. For a given time zone, methods are provided to return information such as the time zone name, country, local time and whether the zone uses daylight savings time. For daylight savings, you can obtain detailed information on the transitions, including when they occur and the time offset of each transition.

The Qt API documentation covers provided functions in detail. Let's look at an example application that demonstrates some of the capabilities of the QTimeZone class.

Example Program

The complete compilable source code for this example, including qmake project file, is available for download (2). The example is a widget-based graphical application that allows selecting a time zone and seeing some of the information about the time zone that QTimeZone can return.

The main program and Qt designer form are standard Qt desktop code, so I won't discuss them here. We'll just focus on the interesting parts that work with the QTimeZone class.

In the constructor for our widget class, we need to fill in a combo box with the available time zones. We can do that by calling the static method QTimeZone::availableTimeZoneIds(). It returns a list of time zone identifiers that are also suitable text for showing in the combo box.

When a time zone is selected by the user in the combo box, we will want to update the UI to reflect the details for that time zone. We'll do that in a slot. So, in the constructor we need to connect the combo box's currentIndexChanged method to that slot, which is called UpdateFields(). Finally, we should call the slot once to initialize the UI with the current value of the combo box.

Here are the relevant lines of code from the file widget.cpp. I've shown the QTimeZone-specific code in bold.

#include <QDebug>
#include <QByteArray>
#include <QDateTime>
#include <QList>
#include <QTimeZone>

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    // Fill in combo box.
    QList<QByteArray> ids = QTimeZone::availableTimeZoneIds();
    foreach (QByteArray id, ids) {
        ui->timeZoneComboBox->addItem(id);
    }

    // Connect combo box to slot to update fields.
    connect(ui->timeZoneComboBox, SIGNAL(currentIndexChanged(int)), SLOT(UpdateFields()));

    // Update fields for initial value.
    UpdateFields();
}

The remaining code in widget.cpp is the implementation of the slot, UpdateFields(). The program first gets the time zone identifier from the currently selected item in the combo box. We can then construct a QTimeZone object, passing the identifier into the constructor.

Given the QTimeZone object, we can now call various methods to get information about the time zone and update the user interface. As is good practice, we call the isValid() method to ensure that we have a valid time zone object before calling other methods.

A few of the methods require additional parameters. For example, the method isDaylightTime(), which returns whether daylight savings time is in effect, requires a date and time. We use the current date and time for this.

The relevant code from widget.cpp is shown below.

void Widget::UpdateFields() {

    QByteArray id = ui->timeZoneComboBox->currentText().toLatin1();
    QTimeZone zone = QTimeZone(id);

    // Fill in fields for current time zone.
    if (zone.isValid()) {
        ui->descriptionLabel->setText(tr("<b>Description:</b> ") + id);
        ui->countryLabel->setText(tr("<b>Country:</b> ") + QLocale::countryToString(zone.country()));
        ui->hasDaylightTimeCheckBox->setChecked(zone.hasDaylightTime());
        ui->isDaylightTimeCheckBox->setChecked(zone.isDaylightTime(QDateTime::currentDateTime()));
        ui->hasTransitionsCheckBox->setChecked(zone.hasTransitions());
        QDateTime zoneTime = QDateTime(QDate::currentDate(), QTime::currentTime(), zone).toLocalTime();
        ui->dateEdit->setDate(zoneTime.date());
        ui->timeEdit->setTime(zoneTime.time());

        QTimeZone::OffsetData offset = zone.nextTransition(QDateTime::currentDateTime());
        if (offset.atUtc != QDateTime()) {
            ui->nextTransitionLabel->setEnabled(true);
            ui->nextTransitionLabel->setText(tr("<b>Next transition:</b> %1").arg(offset.atUtc.toString()));
        } else {
            ui->nextTransitionLabel->setEnabled(false);
            ui->nextTransitionLabel->setText(tr("<b>Next transition:</b> none"));
        }
    }
}

A couple of screen shots showing the application running are displayed below. By selecting a time zone from the combo box, you can see information about that particular time zone.

Exploring the time zone data can reveal some interesting facts about world time. For example, the continent of Antarctica has no less than ten time zones, some of which use daylight savings time while others do not. A few time zones are not multiples of one-hour intervals from other zones, such as Newfoundland in Canada and the country of India, which are multiples of thirty minutes. Nepal has an unusual offset, which is UTC plus 5 hours and 45 minutes. On my Ubuntu Linux desktop system, information is provided for a 454 time zones.

Summary

While Qt's QDate, QTime and QDateTime classes provide facilities for basic time and date handling, should you need detailed information about time zones, you can now use the QTimeZone class to do so in a platform-independent manner.

References

  1. qt-project.org/doc/qt-5/qtimezone.html, QTimeZone API documentation
  2. qtimezone.zip, Source code for example program

Interested in Qt & QML?

Read more articles from the category Qt & QML

About the author

Jeff Tranter

Bio:

Jeff Tranter is a Qt Consulting Manager at ICS. Jeff oversees the architectural and high-level design of software systems for clients. Jeff’s leadership organizes global teams of developers on desktop and embedded applications.