QDateTime::addSecs does not return new object
-
[Working on Qt 6.5]
Hello,
My problem is two-fold.
I have the following code to update my QML date and time:
void CGeneralController::updateDateTime() { QDateTime myCurrentDateTimeUtc = QDateTime::currentDateTimeUtc(); theCurrentDateTime = myCurrentDateTimeUtc.addSecs(theTimeDifferenceSeconds); theDate = theCurrentDateTime.toString("dd/MM/yyyy"); emit dateChanged(); theTime = theCurrentDateTime.toString("hh:mm"); emit timeChanged(); }
At this point,
addSecs
is working as expected because I can see indeed thattheTime
is correctly updated with thetimeDifferenceSeconds
which in this case is value7200
.Next,
theCurrentDateTime
is used to set the maximum in aQDateTimeAxis
object. Instead of setting the correct time in the axis, the Framework sets a+7200
offset, which would be the case if one uses the local time as the calculation basis. However, this shouldn't be the case, as inside the functionupdateDateTime
I am already adding this offset when needed.So,
Problem 1
I don't understand why my date time object is handled differently when I set it to theQDateTimeAxis
. I have also checked that thetimeSpec()
in this case is correctlyUTC
so the offset should remain the same.Problem 2
According to the documentation of addSecs, this function will return a newQDateTime
object. However, when I introduce the following line inside my functionvoid CGeneralController::updateDateTime()
{
QDateTime myCurrentDateTimeUtc = QDateTime::currentDateTimeUtc();
theCurrentDateTime = myCurrentDateTimeUtc.addSecs(theTimeDifferenceSeconds);
Q_ASSERT(myCurrentDateTimeUtc != theCurrentDateTime);
theDate = theCurrentDateTime.toString("dd/MM/yyyy");
emit dateChanged();
theTime = theCurrentDateTime.toString("hh:mm");
emit timeChanged();
}my application does crash, which means that the two objects are the same. This operator actually checks all date, time and time zone, so the described behavior makes no sense to me.
I have also checked the implementation of
addSecs
which makes use of theaddMSecs
here and I can see indeed that a newQDateTime dt(*this)
object is contructed and returned. So again this is super strange, why do I get the assertion?Last, some time ago I had made a related post regarding date and time used in axis https://forum.qt.io/topic/151744/bug-qdatetimeaxis maybe this helps as well.
Thank you.
-
Alright, I have finally gotten a clear reply from the support. Quoting:
Right now, the Qt Charts and Qt Graphs modules do not support displaying QDateTimeAxis values using a specific timezone:
- Previously, it always used the local timezone
- Now, now with the fix from https://codereview.qt-project.org/c/qt/qtgraphs/+/576813/3/src/graphs2d/axis/datetimeaxis/qdatetimeaxis.cpp#b163 , it always uses UTC
So yes, for now, you'll unfortunately need to manually adjust your data to get the display that you want.
Please note: The Qt Charts module is deprecated, and the feature will only be implemented in the new Qt Graphs module.You can follow the requested feature here.
To sum up, if you still use
QtCharts
andQDateTimeAxis
, always make sure to manually "correct" the time-zone offset against theLocalTime
time spec before you set the new object to the axis. -
[Working on Qt 6.5]
Hello,
My problem is two-fold.
I have the following code to update my QML date and time:
void CGeneralController::updateDateTime() { QDateTime myCurrentDateTimeUtc = QDateTime::currentDateTimeUtc(); theCurrentDateTime = myCurrentDateTimeUtc.addSecs(theTimeDifferenceSeconds); theDate = theCurrentDateTime.toString("dd/MM/yyyy"); emit dateChanged(); theTime = theCurrentDateTime.toString("hh:mm"); emit timeChanged(); }
At this point,
addSecs
is working as expected because I can see indeed thattheTime
is correctly updated with thetimeDifferenceSeconds
which in this case is value7200
.Next,
theCurrentDateTime
is used to set the maximum in aQDateTimeAxis
object. Instead of setting the correct time in the axis, the Framework sets a+7200
offset, which would be the case if one uses the local time as the calculation basis. However, this shouldn't be the case, as inside the functionupdateDateTime
I am already adding this offset when needed.So,
Problem 1
I don't understand why my date time object is handled differently when I set it to theQDateTimeAxis
. I have also checked that thetimeSpec()
in this case is correctlyUTC
so the offset should remain the same.Problem 2
According to the documentation of addSecs, this function will return a newQDateTime
object. However, when I introduce the following line inside my functionvoid CGeneralController::updateDateTime()
{
QDateTime myCurrentDateTimeUtc = QDateTime::currentDateTimeUtc();
theCurrentDateTime = myCurrentDateTimeUtc.addSecs(theTimeDifferenceSeconds);
Q_ASSERT(myCurrentDateTimeUtc != theCurrentDateTime);
theDate = theCurrentDateTime.toString("dd/MM/yyyy");
emit dateChanged();
theTime = theCurrentDateTime.toString("hh:mm");
emit timeChanged();
}my application does crash, which means that the two objects are the same. This operator actually checks all date, time and time zone, so the described behavior makes no sense to me.
I have also checked the implementation of
addSecs
which makes use of theaddMSecs
here and I can see indeed that a newQDateTime dt(*this)
object is contructed and returned. So again this is super strange, why do I get the assertion?Last, some time ago I had made a related post regarding date and time used in axis https://forum.qt.io/topic/151744/bug-qdatetimeaxis maybe this helps as well.
Thank you.
This is working as expected for me, no assertion:
QDateTime myCurrentDateTimeUtc = QDateTime::currentDateTimeUtc(); auto theCurrentDateTime = myCurrentDateTimeUtc.addSecs(1234); Q_ASSERT(myCurrentDateTimeUtc != theCurrentDateTime);
I would say theTimeDifferenceSeconds is 0. Add some debug output to see the values.
-
@Christian-Ehrlicher You are very much welcome! Indeed, I had two calls in that function on start-up of the application. The first one that gave the assertion was using
theTimeDifferenceSeconds
with a value of0
. So that part of my problems is now clear.However, the other one still insists. The following code snippet:
... QDateTime myCurrentDateTime = theGeneralController->getTheCurrentDateTime(); anAxisX->setMax(myCurrentDateTime); QString myDate = myCurrentDateTime.toString("dd/MM/yyyy"); QString myTime = myCurrentDateTime.toString("hh:mm"); qInfo() << "My date and time is: " + myDate + " "+ myTime; ...
prints:
"My date and time is: 18/07/2024 14:26"
but the maximum timepoint of my graphs keeps on being set to two hours later.
I tried setting first the minimum but with no effect.
-
To make it even more straightforward:
... anAxisX->setMin(QDateTime::currentDateTimeUtc()); anAxisX->setMax(QDateTime::currentDateTime()); qInfo() << "My current date time utc: " << QDateTime::currentDateTimeUtc().toString("dd/MM/yyyy hh:mm"); qInfo() << "My current date time: " << QDateTime::currentDateTime().toString("dd/MM/yyyy hh:mm"); ...
This is what I get with this setting
What I should get is a two hour difference as I am on CEST (UTC+2) as the log prints:
My current date time utc: "18/07/2024 13:11" My current date time: "18/07/2024 15:11"
-
I don't know anything about QDateTime axis but I would say it is using local time. If this is a bug or expected or can be changed is out of my knowledge - I don't use QML.
-
@Christian-Ehrlicher Thank you for your contribution and help.
Alright I have managed to reach a reasonable explanation. The following code snippet:
... QDateTime myCurrentDateTime = theGeneralController->getTheCurrentDateTime(); int myBeforeOffset = myCurrentDateTime.offsetFromUtc(); Qt::TimeSpec myBeforeTimeSpec = myCurrentDateTime.timeSpec(); anAxisX->setMax(myCurrentDateTime); QDateTime myAfterMax = anAxisX->max(); int myAfterOffset = myAfterMax.offsetFromUtc(); Qt::TimeSpec myAfterTimeSpec = myAfterMax.timeSpec(); qInfo() << "My before offset: " + QString::number(myBeforeOffset); qInfo() << "My before time spec: " + QString::number(myBeforeTimeSpec); qInfo() << "My after offset: " + QString::number(myAfterOffset); qInfo() << "My after time spec: " + QString::number(myAfterTimeSpec); ...
prints
"My before offset: 0" "My before time spec: 1" // This is Qt::UTC "My after offset: 7200" "My after time spec: 0" // This is Qt::LocalTime
So, it seems that the
QDateTimeAxis
is indeed converting the passedQDateTime
object fromUTC
toLocalTime
internally. I don't know if this should be considered a bug, but I have not found any mention of this in the documentation. I have created a ticket with the support team on this, and I will update this thread once I have an answer from them as well. -
Alright, I have finally gotten a clear reply from the support. Quoting:
Right now, the Qt Charts and Qt Graphs modules do not support displaying QDateTimeAxis values using a specific timezone:
- Previously, it always used the local timezone
- Now, now with the fix from https://codereview.qt-project.org/c/qt/qtgraphs/+/576813/3/src/graphs2d/axis/datetimeaxis/qdatetimeaxis.cpp#b163 , it always uses UTC
So yes, for now, you'll unfortunately need to manually adjust your data to get the display that you want.
Please note: The Qt Charts module is deprecated, and the feature will only be implemented in the new Qt Graphs module.You can follow the requested feature here.
To sum up, if you still use
QtCharts
andQDateTimeAxis
, always make sure to manually "correct" the time-zone offset against theLocalTime
time spec before you set the new object to the axis. -