When I plot this, the time always shows 8 hours + the correct number of seconds (for my current dataset at least). For the above example, the y-axis shows "08:00:18".

Any ideas on what I'm doing wrong here?
Thanks
Jaco

October 30, 2013, 20:24by DerManu

Does your timezone happen to be +/-8?

October 31, 2013, 02:44by Jaco Naude

Yes you are correct, my timezone is GMT +8. Is it possible to make the axis timezone independent?

October 31, 2013, 22:29by DerManu

You have to correctly carry the time zone information. This basically works two ways:

You can just let QDateTime do all the work, and just use the toMSecsSinceEpoch function. It automatically takes care that the time zones are interpreted correctly (since internally, QCustomPlot again calls fromMSecsSinceEpoch).

If you want to do the conversion to seconds yourself as in your example, make sure you use the UTC time to do that. This is necessary because the time reference point 0 corresponds to 01.01.1970-00:00:00 UTC. You could do that like this:

The first shows funny times where the higher values are on the bottom of the y-axis compared to lower values being on the top of the y-axis. I've printed the date time and it seems correct. For example, "Mon Jan 1 00:00:46 1900" for 46 seconds. Calling toMSecsSinceEpoch()/1000.0 on that QDateTime object results in the funny values.

The second solution does not make any difference. All times still have a +8 hour offset.

Any idea what's going wrong here? Thanks!

November 6, 2013, 20:19by DerManu

That is very peculiar. Here's a simple demo of what goes on outside and inside QCP:

And if I comment out the time = time.toUTC();, it prints as expected the "wrong" times:"01:00:05" "02:30:05"

Is this different on your system? I've tested this on linux, Qt 4.7.4, 4.8.3, 5.0.2

November 12, 2013, 06:45by Jaco Naude

Hi again,

I created an example that demonstrates the problem. I added an additional plot to the plot-examples example. The cpp implementation is below so you can just add the function definition in the header and extend your case statement in setupDemo() to use it.

There is a boolean variable called use_toUtc_approach which you can toggle to switch between the two solutions you proposed.

This example fails for us (note that it fails differently depending on the value of use_toUtc_approach). We are testing on Qt 5.1, Win7 & Ubuntu & CentOs (same behavior everywhere). Can you please check if this works for you?

A small observation first: in line 20 and 38 you use the method toUTC() in a way that has no effect. It doesn't change the current object, but returns a changed datetime, so you should write time1 = time1.toUTC(); instead.

Now, here's the code how it works with using the method where toMSecsSinceEpoch is used to generate the times:

We completely stay in UTC time. This is necessary because the bars plottable anchors the base of the bar at value 0, which only in UTC is 00:00:00. If interpreted in local time, the bars will have their base at your local timezone offset and eventually generate upside down bars. To completely stay in UTC we also need to use QCPAxis::setDateTimeSpec(Qt::UTC) in line 41 which is new in QCP 1.1.0.

Now there's another pitfall that's worth mentioning: Passing just a time like "00:05:36" to QDateTime::fromString defaults to the date 01.01.1900. This is not the UTC 0, which is 01.01.1970. So If we had left the date unspecified in lines 14 and 21, we would have ended up with gigantic negative bars from 1970 (the UTC 0) down to 1900. Obviously, if only viewing hh:mm:ss, this results in seemngly random tick labels. That's why I let it also print day month and year in the above example, to figure this out.

Okay, now how to do it with the explicitly constructed runtime_dbl from hour, minute and second values:

There's not much difference, apart from the fact that now we can get away with not specifying the date explicitly in the QDateTime::fromString method. This is because we use only the time part of the datetime object and construct our runtime_dbl from that, effectively starting from the correct UTC 0.

The fact that the bars plottable always places its bar base at value 0 is unfortunate and will be changed in a future release. In your case, as shown above, this behaviour is okay if we set the axis timespec to be UTC, where the value 0 actually is time 00:00:00. I hope switching to QCustomPlot 1.1.0 is an option for you, because before that I'm afraid the bars plottable will always place its base at the local time offset.

November 18, 2013, 07:29by Jaco Naude

Thanks for the detailed explanation and taking the time to figure this one out. I tested it on my side as well and it works perfectly after I upgraded to v1.1.

February 6, 2018, 09:50by George

Hi everyone! I'm trying to create some plot with time on x axis, and function on the second axis. As reference I used simple Graphic example! So what's the problem, how can I extract data from QDateTime vector, and just set it into my plot (x axis)? I can't find how do that simple!