##// END OF EJS Templates
Merge branch 'feature/DateTimeUTC' into develop
Alexandre Leroux -
r455:a774a1678512 merge
parent child
Show More
@@ -0,0 +1,19
1 #ifndef SCIQLOP_DATEUTILS_H
2 #define SCIQLOP_DATEUTILS_H
3
4 #include "CoreGlobal.h"
5
6 #include <QDateTime>
7
8 /**
9 * Utility class with methods for dates
10 */
11 struct SCIQLOP_CORE_EXPORT DateUtils {
12 /// Converts seconds (since epoch) to datetime. By default, the datetime is in UTC
13 static QDateTime dateTime(double secs, Qt::TimeSpec timeSpec = Qt::UTC) noexcept;
14
15 /// Converts datetime to seconds since epoch
16 static double secondsSinceEpoch(const QDateTime &dateTime) noexcept;
17 };
18
19 #endif // SCIQLOP_DATEUTILS_H
@@ -0,0 +1,13
1 #include "Common/DateUtils.h"
2
3 QDateTime DateUtils::dateTime(double secs, Qt::TimeSpec timeSpec) noexcept
4 {
5 // Uses msecs to be Qt 4 compatible
6 return QDateTime::fromMSecsSinceEpoch(secs * 1000., timeSpec);
7 }
8
9 double DateUtils::secondsSinceEpoch(const QDateTime &dateTime) noexcept
10 {
11 // Uses msecs to be Qt 4 compatible
12 return dateTime.toMSecsSinceEpoch() / 1000.;
13 }
@@ -36,7 +36,6
36
36
37 #include <QAction>
37 #include <QAction>
38 #include <QDate>
38 #include <QDate>
39 #include <QDateTime>
40 #include <QDir>
39 #include <QDir>
41 #include <QFileDialog>
40 #include <QFileDialog>
42 #include <QToolBar>
41 #include <QToolBar>
@@ -23,7 +23,7 struct Unit {
23 inline bool operator!=(const Unit &other) const { return !(*this == other); }
23 inline bool operator!=(const Unit &other) const { return !(*this == other); }
24
24
25 QString m_Name; ///< Unit name
25 QString m_Name; ///< Unit name
26 bool m_TimeUnit; ///< The unit is a unit of time
26 bool m_TimeUnit; ///< The unit is a unit of time (UTC)
27 };
27 };
28
28
29 /**
29 /**
@@ -3,18 +3,18
3
3
4 #include <QObject>
4 #include <QObject>
5
5
6 #include <QDateTime>
7 #include <QDebug>
6 #include <QDebug>
8
7
8 #include <Common/DateUtils.h>
9 #include <Common/MetaTypes.h>
9 #include <Common/MetaTypes.h>
10
10
11 /**
11 /**
12 * @brief The SqpDateTime struct holds the information of time parameters
12 * @brief The SqpDateTime struct holds the information of time parameters
13 */
13 */
14 struct SqpDateTime {
14 struct SqpDateTime {
15 /// Start time
15 /// Start time (UTC)
16 double m_TStart;
16 double m_TStart;
17 /// End time
17 /// End time (UTC)
18 double m_TEnd;
18 double m_TEnd;
19
19
20 bool contains(const SqpDateTime &dateTime) const noexcept
20 bool contains(const SqpDateTime &dateTime) const noexcept
@@ -30,10 +30,9 struct SqpDateTime {
30
30
31 inline QDebug operator<<(QDebug d, SqpDateTime obj)
31 inline QDebug operator<<(QDebug d, SqpDateTime obj)
32 {
32 {
33 auto tendDateTimeStart = QDateTime::fromMSecsSinceEpoch(obj.m_TStart * 1000);
33 auto tendDateTimeStart = DateUtils::dateTime(obj.m_TStart);
34 auto tendDateTimeEnd = QDateTime::fromMSecsSinceEpoch(obj.m_TEnd * 1000);
34 auto tendDateTimeEnd = DateUtils::dateTime(obj.m_TEnd);
35
35
36 // QDebug << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
37 d << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
36 d << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
38 return d;
37 return d;
39 }
38 }
@@ -8,7 +8,6
8 #include <Data/IDataSeries.h>
8 #include <Data/IDataSeries.h>
9 #include <Time/TimeController.h>
9 #include <Time/TimeController.h>
10
10
11 #include <QDateTime>
12 #include <QMutex>
11 #include <QMutex>
13 #include <QThread>
12 #include <QThread>
14 #include <QUuid>
13 #include <QUuid>
@@ -1,9 +1,10
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableModel.h>
2 #include <Variable/VariableModel.h>
3
3
4 #include <Common/DateUtils.h>
5
4 #include <Data/IDataSeries.h>
6 #include <Data/IDataSeries.h>
5
7
6 #include <QDateTime>
7 #include <QSize>
8 #include <QSize>
8 #include <unordered_map>
9 #include <unordered_map>
9
10
@@ -150,8 +151,8 QVariant VariableModel::data(const QModelIndex &index, int role) const
150 if (role == Qt::DisplayRole) {
151 if (role == Qt::DisplayRole) {
151 if (auto variable = impl->m_Variables.at(index.row()).get()) {
152 if (auto variable = impl->m_Variables.at(index.row()).get()) {
152 /// Lambda function that builds the variant to return for a time value
153 /// Lambda function that builds the variant to return for a time value
153 auto dateTimeVariant = [](double time) {
154 auto dateTimeVariant = [](double secs) {
154 auto dateTime = QDateTime::fromMSecsSinceEpoch(time * 1000.);
155 auto dateTime = DateUtils::dateTime(secs);
155 return dateTime.toString(DATETIME_FORMAT);
156 return dateTime.toString(DATETIME_FORMAT);
156 };
157 };
157
158
@@ -1,6 +1,7
1 #include "TimeWidget/TimeWidget.h"
1 #include "TimeWidget/TimeWidget.h"
2 #include "ui_TimeWidget.h"
2 #include "ui_TimeWidget.h"
3
3
4 #include <Common/DateUtils.h>
4 #include <SqpApplication.h>
5 #include <SqpApplication.h>
5 #include <Time/TimeController.h>
6 #include <Time/TimeController.h>
6
7
@@ -22,13 +23,15 TimeWidget::TimeWidget(QWidget *parent) : QWidget{parent}, ui{new Ui::TimeWidget
22 &TimeController::onTimeNotify);
23 &TimeController::onTimeNotify);
23
24
24 // Initialisation
25 // Initialisation
25 ui->startDateTimeEdit->setDateTime(
26 auto endDateTime = QDateTime::currentDateTimeUtc();
26 QDateTime::currentDateTime().addSecs(-3600)); // one hour berefore
27 auto startDateTime = endDateTime.addSecs(-3600); // one hour before
27 ui->endDateTimeEdit->setDateTime(QDateTime::currentDateTime());
28
29 ui->startDateTimeEdit->setDateTime(startDateTime);
30 ui->endDateTimeEdit->setDateTime(endDateTime);
31
32 auto dateTime = SqpDateTime{DateUtils::secondsSinceEpoch(startDateTime),
33 DateUtils::secondsSinceEpoch(endDateTime)};
28
34
29 auto dateTime
30 = SqpDateTime{QDateTime::currentDateTime().addSecs(-3600).toMSecsSinceEpoch() / 1000.0,
31 QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000.0};
32 sqpApp->timeController().onTimeToUpdate(dateTime);
35 sqpApp->timeController().onTimeToUpdate(dateTime);
33 }
36 }
34
37
@@ -40,9 +43,8 TimeWidget::~TimeWidget()
40
43
41 void TimeWidget::onTimeUpdateRequested()
44 void TimeWidget::onTimeUpdateRequested()
42 {
45 {
43 auto dateTime = SqpDateTime{
46 auto dateTime = SqpDateTime{DateUtils::secondsSinceEpoch(ui->startDateTimeEdit->dateTime()),
44 static_cast<double>(ui->startDateTimeEdit->dateTime().toMSecsSinceEpoch() / 1000.),
47 DateUtils::secondsSinceEpoch(ui->endDateTimeEdit->dateTime())};
45 static_cast<double>(ui->endDateTimeEdit->dateTime().toMSecsSinceEpoch()) / 1000.};
46
48
47 emit timeUpdated(std::move(dateTime));
49 emit timeUpdated(std::move(dateTime));
48 }
50 }
@@ -25,6 +25,7 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis)
25 if (isTimeAxis) {
25 if (isTimeAxis) {
26 auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create();
26 auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create();
27 dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT);
27 dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT);
28 dateTicker->setDateTimeSpec(Qt::UTC);
28
29
29 return dateTicker;
30 return dateTicker;
30 }
31 }
@@ -1,6 +1,8
1 #include "Visualization/VisualizationGraphRenderingDelegate.h"
1 #include "Visualization/VisualizationGraphRenderingDelegate.h"
2 #include "Visualization/qcustomplot.h"
2 #include "Visualization/qcustomplot.h"
3
3
4 #include <Common/DateUtils.h>
5
4 namespace {
6 namespace {
5
7
6 const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz");
8 const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz");
@@ -14,9 +16,12 const auto TRACER_TIMEOUT = 500;
14 QString formatValue(double value, const QCPAxis &axis)
16 QString formatValue(double value, const QCPAxis &axis)
15 {
17 {
16 // If the axis is a time axis, formats the value as a date
18 // If the axis is a time axis, formats the value as a date
17 return qSharedPointerDynamicCast<QCPAxisTickerDateTime>(axis.ticker())
19 if (auto axisTicker = qSharedPointerDynamicCast<QCPAxisTickerDateTime>(axis.ticker())) {
18 ? QCPAxisTickerDateTime::keyToDateTime(value).toString(DATETIME_FORMAT)
20 return DateUtils::dateTime(value, axisTicker->dateTimeSpec()).toString(DATETIME_FORMAT);
19 : QString::number(value);
21 }
22 else {
23 return QString::number(value);
24 }
20 }
25 }
21
26
22 void initPointTracerStyle(QCPItemTracer &tracer) noexcept
27 void initPointTracerStyle(QCPItemTracer &tracer) noexcept
@@ -47,6 +47,9
47 <property name="calendarPopup">
47 <property name="calendarPopup">
48 <bool>true</bool>
48 <bool>true</bool>
49 </property>
49 </property>
50 <property name="timeSpec">
51 <enum>Qt::UTC</enum>
52 </property>
50 </widget>
53 </widget>
51 </item>
54 </item>
52 <item>
55 <item>
@@ -76,6 +79,9
76 <property name="calendarPopup">
79 <property name="calendarPopup">
77 <bool>true</bool>
80 <bool>true</bool>
78 </property>
81 </property>
82 <property name="timeSpec">
83 <enum>Qt::UTC</enum>
84 </property>
79 </widget>
85 </widget>
80 </item>
86 </item>
81 <item>
87 <item>
@@ -2,6 +2,7
2 #include "AmdaDefs.h"
2 #include "AmdaDefs.h"
3 #include "AmdaResultParser.h"
3 #include "AmdaResultParser.h"
4
4
5 #include <Common/DateUtils.h>
5 #include <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
6 #include <Network/NetworkController.h>
7 #include <Network/NetworkController.h>
7 #include <SqpApplication.h>
8 #include <SqpApplication.h>
@@ -31,7 +32,7 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
31 /// Formats a time to a date that can be passed in URL
32 /// Formats a time to a date that can be passed in URL
32 QString dateFormat(double sqpDateTime) noexcept
33 QString dateFormat(double sqpDateTime) noexcept
33 {
34 {
34 auto dateTime = QDateTime::fromMSecsSinceEpoch(sqpDateTime * 1000.);
35 auto dateTime = DateUtils::dateTime(sqpDateTime);
35 return dateTime.toString(AMDA_TIME_FORMAT);
36 return dateTime.toString(AMDA_TIME_FORMAT);
36 }
37 }
37
38
@@ -1,5 +1,6
1 #include "AmdaResultParser.h"
1 #include "AmdaResultParser.h"
2
2
3 #include <Common/DateUtils.h>
3 #include <Data/ScalarSeries.h>
4 #include <Data/ScalarSeries.h>
4
5
5 #include <QDateTime>
6 #include <QDateTime>
@@ -33,10 +34,17 const auto UNIT_REGEX = QRegularExpression{QStringLiteral("-\\s*Units\\s*:\\s*(.
33 double doubleDate(const QString &stringDate) noexcept
34 double doubleDate(const QString &stringDate) noexcept
34 {
35 {
35 auto dateTime = QDateTime::fromString(stringDate, DATE_FORMAT);
36 auto dateTime = QDateTime::fromString(stringDate, DATE_FORMAT);
36 return dateTime.isValid() ? (dateTime.toMSecsSinceEpoch() / 1000.)
37 dateTime.setTimeSpec(Qt::UTC);
38 return dateTime.isValid() ? DateUtils::secondsSinceEpoch(dateTime)
37 : std::numeric_limits<double>::quiet_NaN();
39 : std::numeric_limits<double>::quiet_NaN();
38 }
40 }
39
41
42 /// Checks if a line is a comment line
43 bool isCommentLine(const QString &line)
44 {
45 return line.startsWith("#");
46 }
47
40 /**
48 /**
41 * Reads stream to retrieve x-axis unit
49 * Reads stream to retrieve x-axis unit
42 * @param stream the stream to read
50 * @param stream the stream to read
@@ -47,20 +55,16 Unit readXAxisUnit(QTextStream &stream)
47 {
55 {
48 QString line{};
56 QString line{};
49
57
50 if (stream.readLineInto(&line)) {
58 // Searches unit in the comment lines
59 while (stream.readLineInto(&line) && isCommentLine(line)) {
51 auto match = UNIT_REGEX.match(line);
60 auto match = UNIT_REGEX.match(line);
52 if (match.hasMatch()) {
61 if (match.hasMatch()) {
53 return Unit{match.captured(1), true};
62 return Unit{match.captured(1), true};
54 }
63 }
55 else {
56 qCWarning(LOG_AmdaResultParser())
57 << QObject::tr("Can't read unit: invalid line %1").arg(line);
58 }
59 }
60 else {
61 qCWarning(LOG_AmdaResultParser()) << QObject::tr("Can't read unit: end of file");
62 }
64 }
63
65
66 qCWarning(LOG_AmdaResultParser()) << QObject::tr("The unit could not be found in the file");
67
64 // Error cases
68 // Error cases
65 return Unit{{}, true};
69 return Unit{{}, true};
66 }
70 }
@@ -76,32 +80,36 QPair<QVector<double>, QVector<double> > readResults(QTextStream &stream)
76 auto valuesData = QVector<double>{};
80 auto valuesData = QVector<double>{};
77
81
78 QString line{};
82 QString line{};
83
79 while (stream.readLineInto(&line)) {
84 while (stream.readLineInto(&line)) {
80 auto lineData = line.split(RESULT_LINE_SEPARATOR, QString::SkipEmptyParts);
85 // Ignore comment lines
81 if (lineData.size() == 2) {
86 if (!isCommentLine(line)) {
82 // X : the data is converted from date to double (in secs)
87 auto lineData = line.split(RESULT_LINE_SEPARATOR, QString::SkipEmptyParts);
83 auto x = doubleDate(lineData.at(0));
88 if (lineData.size() == 2) {
84
89 // X : the data is converted from date to double (in secs)
85 // Value
90 auto x = doubleDate(lineData.at(0));
86 bool valueOk;
91
87 auto value = lineData.at(1).toDouble(&valueOk);
92 // Value
88
93 bool valueOk;
89 // Adds result only if x and value are valid
94 auto value = lineData.at(1).toDouble(&valueOk);
90 if (!std::isnan(x) && !std::isnan(value) && valueOk) {
95
91 xData.push_back(x);
96 // Adds result only if x and value are valid
92 valuesData.push_back(value);
97 if (!std::isnan(x) && !std::isnan(value) && valueOk) {
98 xData.push_back(x);
99 valuesData.push_back(value);
100 }
101 else {
102 qCWarning(LOG_AmdaResultParser())
103 << QObject::tr(
104 "Can't retrieve results from line %1: x and/or value are invalid")
105 .arg(line);
106 }
93 }
107 }
94 else {
108 else {
95 qCWarning(LOG_AmdaResultParser())
109 qCWarning(LOG_AmdaResultParser())
96 << QObject::tr(
110 << QObject::tr("Can't retrieve results from line %1: invalid line").arg(line);
97 "Can't retrieve results from line %1: x and/or value are invalid")
98 .arg(line);
99 }
111 }
100 }
112 }
101 else {
102 qCWarning(LOG_AmdaResultParser())
103 << QObject::tr("Can't retrieve results from line %1: invalid line").arg(line);
104 }
105 }
113 }
106
114
107 return qMakePair(std::move(xData), std::move(valuesData));
115 return qMakePair(std::move(xData), std::move(valuesData));
@@ -131,13 +139,12 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(const QString &filePath)
131 return nullptr;
139 return nullptr;
132 }
140 }
133
141
134 // Ignore comments lines
135 stream.readLine();
136
137 // Reads x-axis unit
142 // Reads x-axis unit
143 stream.seek(0); // returns to the beginning of the file
138 auto xAxisUnit = readXAxisUnit(stream);
144 auto xAxisUnit = readXAxisUnit(stream);
139
145
140 // Reads results
146 // Reads results
147 stream.seek(0); // returns to the beginning of the file
141 auto results = readResults(stream);
148 auto results = readResults(stream);
142
149
143 return std::make_shared<ScalarSeries>(std::move(results.first), std::move(results.second),
150 return std::make_shared<ScalarSeries>(std::move(results.first), std::move(results.second),
@@ -99,7 +99,7 void TestAmdaResultParser::testReadTxt_data()
99 // ////////// //
99 // ////////// //
100
100
101 auto dateTime = [](int year, int month, int day, int hours, int minutes, int seconds) {
101 auto dateTime = [](int year, int month, int day, int hours, int minutes, int seconds) {
102 return QDateTime{{year, month, day}, {hours, minutes, seconds}};
102 return QDateTime{{year, month, day}, {hours, minutes, seconds}, Qt::UTC};
103 };
103 };
104
104
105 // Valid file
105 // Valid file
@@ -5,7 +5,6
5
5
6 #include <cmath>
6 #include <cmath>
7
7
8 #include <QDateTime>
9 #include <QFuture>
8 #include <QFuture>
10 #include <QThread>
9 #include <QThread>
11 #include <QtConcurrent/QtConcurrent>
10 #include <QtConcurrent/QtConcurrent>
General Comments 0
You need to be logged in to leave comments. Login now