Reputation: 613
I am using QtCharts to display simulation data. The simulation starts at time zero, but my chart axis always seems to start at 19 hours. This confounds me. The set up of the chart is straight forward:
std::vector<SimData> data;
// ... Populate data
auto series = new QLineSeries();
for(auto i : data)
{
// Append time in milliseconds and a value
series->append(i.msTime, i.value);
}
this->legend()->hide();
this->addSeries(series);
this->axisX = new QDateTimeAxis;
this->axisX->setTickCount(10);
this->axisX->setFormat("HH:mm:ss");
this->axisX->setTitleText("Sim Time");
this->axisX->setMin(QDateTime());
this->addAxis(this->axisX, Qt::AlignBottom);
series->attachAxis(this->axisX);
this->axisY = new QValueAxis;
this->axisY->setLabelFormat("%i");
this->axisY->setTitleText(x->getID().c_str());
this->addAxis(this->axisY, Qt::AlignLeft);
series->attachAxis(this->axisY);
If I run with no data, but just display the chart, I get this:
If I add data, starting at time zero, the total amount of data is correct, but the time still starts at 19:00:00. Why does the time not start at 00:00:00?
Upvotes: 0
Views: 1597
Reputation: 1
For the lonesome wanderer blah blah. As solution of Tillo Reilly didn't work for me, I did my own (which works). In addition, my code converts timestamp to particular timezone. The thing is - QtCharts don't knows nothing about timezones (but better should to) but know and force-uses local PC timezone in a wierd way. So, if you want to change displayed date/time on charts to specified timezone - the only thing you can do is to modify dataset.
Answer to original question
auto temp_time = QDateTime::fromSecsSinceEpoch( timestamp );
auto local_offset = temp_time.offsetFromUtc();
auto fixed_timestamp = timestamp - local_offset;
With specified timezone
auto temp_time = QDateTime::fromSecsSinceEpoch( timestamp );
auto local_offset = temp_time.offsetFromUtc();
temp_time.setTimeSpec( Qt::TimeZone );
temp_time.setTimeZone( QTimeZone("Europe/Moscow") ); //for example
auto timezone_offset = temp_time.offsetFromUtc();
auto fixed_timestamp = timestamp + timezone_offset - local_offset;
important notice 1: you shouldn't create any random QDateTime object to calculate offsets, for example with functions like QDateTime::currentDateTime() or QDateTime::fromSecsSinceEpoch(0) - offset from UTC depends on point in time! So, with functions above you'll get QDateTime object, but its offset from UTC may differ from what you expect.
For the very same reason, you shouldn't calculate offset once and use it for all the dataset, especially for datasets with significant time ranges. The larger your dataset size - the bigger chances are that you'll get into trouble with unexpected Daylight Saving Time somewhere in the middle of it.
important notice 2: I don't know if QtCharts calculates offset from UTC for local timezone for current time or for timestamp passed to it via data series. I really hope it's the latter.
Upvotes: 0
Reputation: 1
For the lonesome wanderer that probably ends up here.
My KISS solution is actually setting the time, then some a second and finally add a new data point:
for(int i = 0; i <= points; i++) {
QDateTime timeStamp;
timeStamp.setDate(QDate(1980, 1, 1));
timeStamp.setTime(QTime(0, 0, 0));
timeStamp = timeStamp.addSecs(i);
data->append(timeStamp.toMSecsSinceEpoch(), /* your y here */);
}
later where the diagram gets painted I used:
QSplineSeries *temps1 = /* wherever you get your series */;
QChart *chTemp = new QChart();
tempAxisX->setTickCount(5);
tempAxisX->setFormat(QString("hh:mm:ss"));
tempAxisX->setTitleText("Time");
chTemp->addAxis(tempAxisX, Qt::AlignBottom);
temps1->attachAxis(tempAxisX);
Hope that that helps a future visitor once (including myself).
Upvotes: 0
Reputation: 613
The problem was indeed confirmed to be UTC offset. SO had a good example of how to get the UTC Offset which I then used to offset the data going into the chart:
Easy way to convert a struct tm (expressed in UTC) to time_t type
I created a utility function from this to use with QDateTimeAxis series data.
double GetUTCOffsetForQDateTimeAxis()
{
time_t zero = 24 * 60 * 60L;
struct tm* timeptr;
int gmtime_hours;
// get the local time for Jan 2, 1900 00:00 UTC
timeptr = localtime(&zero);
gmtime_hours = timeptr->tm_hour;
// if the local time is the "day before" the UTC, subtract 24 hours
// from the hours to get the UTC offset
if(timeptr->tm_mday < 2)
{
gmtime_hours -= 24;
}
return 24.0 + gmtime_hours;
}
Then the data conversion was simple.
std::vector<SimData> data;
// ... Populate data
auto series = new QLineSeries();
const auto utcOffset = sec2ms(hours2sec(GetUTCOffsetForQDateTimeAxis()));
for(auto i : data)
{
// Append time in milliseconds and a value
series->append(i.msTime - utcOffset, i.value);
}
// ...
Upvotes: 0
Reputation: 11
I believe this is because you are on the East Coast (UTC-5) so while 0 represents 12am (2400) at UTC-5 0ms would represent 5 hours earlier (1900 the previous day). I was having the same problem, set my time zone to UTC (under ubuntu) and voila axis started at 0 hours instead of 19.
Upvotes: 1