From af17c2c4e6699834782c5dd199f16143a54b73b3 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Wed, 9 Jul 2014 19:58:18 +0200 Subject: [PATCH] refs #289, negative time values supported, required for time offset --- .../samplesphysicalquantities.cpp | 19 ++++- src/blackmisc/pqphysicalquantity.h | 12 +++ src/blackmisc/pqstring.cpp | 9 ++- src/blackmisc/pqtime.cpp | 76 ++++++++++++++++++- src/blackmisc/pqtime.h | 10 ++- 5 files changed, 115 insertions(+), 11 deletions(-) diff --git a/samples/blackmiscquantities/samplesphysicalquantities.cpp b/samples/blackmiscquantities/samplesphysicalquantities.cpp index f3e12a557..90062ba56 100644 --- a/samples/blackmiscquantities/samplesphysicalquantities.cpp +++ b/samples/blackmiscquantities/samplesphysicalquantities.cpp @@ -15,8 +15,9 @@ namespace BlackMiscTest */ int CSamplesPhysicalQuantities::samples() { - CSpeed parsedPq1 = CPqString::parseToVariant("100 km/h").value(); - CLength parsedPq2 = CPqString::parseToVariant("-33ft").value(); + // parsing + CSpeed parsedPq1 = CPqString::parseToVariant("100.123 km/h").value(); + CLength parsedPq2 = CPqString::parseToVariant("-33.123ft").value(); QVariant parsedPq3 = CPqString::parseToVariant("666"); qDebug() << "parsed" << parsedPq1 << parsedPq2 << parsedPq3; @@ -24,9 +25,19 @@ namespace BlackMiscTest CFrequency frequencyParsed = CPqString::parse("122.8MHz"); qDebug() << "parsed" << speedParsed << speedParsed.valueRoundedWithUnit(2, true) << frequencyParsed << frequencyParsed.valueRoundedWithUnit(2, true); - // cases which must not work - // CLengthUnit du1(CAngleUnit::rad()); + // the time clasas + CTime time1; + time1.parseFromString("11:30"); // hhmm + qDebug() << time1 << time1.toQTime() << time1.formattedHrsMin(); + CTime time2; + time2.parseFromString("-11:30"); // hhmm + qDebug() << time2 << time2.toQTime() << time2.formattedHrsMin(); + + time1 += time2; + qDebug() << time1 << time1.toQTime() << time1.formattedHrsMin(); + + // standard tests CLengthUnit lu1(CLengthUnit::cm()); CLengthUnit lu2(CLengthUnit::ft()); QString lu1s = lu1.toQString(true); diff --git a/src/blackmisc/pqphysicalquantity.h b/src/blackmisc/pqphysicalquantity.h index f4fd4160e..c2c0670e3 100644 --- a/src/blackmisc/pqphysicalquantity.h +++ b/src/blackmisc/pqphysicalquantity.h @@ -219,6 +219,18 @@ namespace BlackMisc return !this->isZeroEpsilonConsidered() && this->m_value < 0; } + //! Make value always positive + void makePositive() + { + if (this->m_value < 0) { this->m_value *= -1.0; } + } + + //! Make value always negative + void makeNegative() + { + if (this->m_value > 0) { this->m_value *= -1.0; } + } + //! \copydoc CValueObject::marshallToDbus virtual void marshallToDbus(QDBusArgument &argument) const override; diff --git a/src/blackmisc/pqstring.cpp b/src/blackmisc/pqstring.cpp index 5893a49b3..2fd3a43f3 100644 --- a/src/blackmisc/pqstring.cpp +++ b/src/blackmisc/pqstring.cpp @@ -95,9 +95,14 @@ namespace BlackMisc */ QVariant CPqString::parseToVariant(const QString &value, SeparatorMode mode) { - static QRegExp rx("([0-9]+)\\s*(\\D*)$"); + static QRegExp rx("([-+]?[0-9]*[\\.,]?[0-9]+)\\s*(\\D*)$"); QVariant v; - if (value.isEmpty()) return v; + + // fine tuning of the string + QString vs = value.trimmed().simplified(); + + // check + if (vs.isEmpty()) return v; if (rx.indexIn(value) < 0) return v; // not a valid number QString unit = rx.cap(2).trimmed(); diff --git a/src/blackmisc/pqtime.cpp b/src/blackmisc/pqtime.cpp index afc95730b..51ff39b9f 100644 --- a/src/blackmisc/pqtime.cpp +++ b/src/blackmisc/pqtime.cpp @@ -6,7 +6,8 @@ namespace BlackMisc { CTime::CTime(int hours, int minutes, int seconds) : CPhysicalQuantity(0, CTimeUnit::nullUnit()) { - double value = hours + minutes / 100.0 + seconds / 10000.0; + bool negative = (hours < 0); + double value = qAbs(hours) + minutes / 100.0 + seconds / 10000.0; if (minutes == 0 && seconds == 0) { (*this) = CTime(hours, CTimeUnit::h()); @@ -18,18 +19,39 @@ namespace BlackMisc else (*this) = CTime(value, CTimeUnit::hms()); } + if (negative) + { + this->makeNegative(); + } } - CTime::CTime(const QTime &time) : CPhysicalQuantity(0, CTimeUnit::nullUnit()) + CTime::CTime(const QTime &time, bool negative) : CPhysicalQuantity(0, CTimeUnit::nullUnit()) { CTime converted(time.hour(), time.minute(), time.second()); (*this) = converted; + if (negative) + { + this->makeNegative(); + } } void CTime::parseFromString(const QString &time) { QTime t; - const QString ts = time.trimmed(); + QString ts = time.trimmed(); + + // deal with sign + double factor = 1.0; + if (ts.startsWith('+')) + { + ts.remove(0, 1); + } + else if (ts.startsWith('-')) + { + factor = -1.0; + ts.remove(0, 1); + } + if (ts.contains(":") && (ts.length() == 8 || ts.length() == 5)) { if (ts.length() == 5) @@ -37,15 +59,27 @@ namespace BlackMisc else if (ts.length() == 8) t = QTime::fromString(ts, "hh:mm:ss"); (*this) = CTime(t); + + // fix sign if required + if (factor < 0) + { + this->setValueSameUnit(this->value() * factor); + } } else - CPhysicalQuantity::parseFromString(ts); + CPhysicalQuantity::parseFromString(time); } QTime CTime::toQTime() const { CTime copy(*this); copy.setUnit(CTimeUnit::hms()); + + // QTime is not defined for negative numbers + // so we use the absolute value here + copy.makePositive(); + + // convert QString s = copy.toQString(false).replace('h', ':').replace('m', ':').replace('s', ""); QTime t = s.length() == 8 ? QTime::fromString(s, "hh:mm:ss") : @@ -60,5 +94,39 @@ namespace BlackMisc parts << t.hour() << t.minute() << t.second(); return parts; } + + QString CTime::formattedHrsMinSec() const + { + QList parts = getHrsMinSecParts(); + QString h = QString("00%1").arg(QString::number(parts.at(0))).right(2); + QString m = QString("00%1").arg(QString::number(parts.at(1))).right(2); + QString s = QString("00%1").arg(QString::number(parts.at(2))).right(2); + + QString fs = QString("%1:%2:%3").arg(h).arg(m).arg(s); + if (this->isNegativeWithEpsilonConsidered()) + { + return QString("-").append(fs); + } + else + { + return fs; + } + } + + QString CTime::formattedHrsMin() const + { + QList parts = getHrsMinSecParts(); + QString h = QString("00%1").arg(QString::number(parts.at(0))).right(2); + QString m = QString("00%1").arg(QString::number(parts.at(1))).right(2); + QString fs = QString("%1:%2").arg(h).arg(m); + if (this->isNegativeWithEpsilonConsidered()) + { + return QString("-").append(fs); + } + else + { + return fs; + } + } } } diff --git a/src/blackmisc/pqtime.h b/src/blackmisc/pqtime.h index 11b913227..3e3393fcf 100644 --- a/src/blackmisc/pqtime.h +++ b/src/blackmisc/pqtime.h @@ -38,7 +38,7 @@ namespace BlackMisc CTime(int hours, int minutes, int seconds = 0); //! By Qt time - CTime(const QTime &time); + CTime(const QTime &time, bool negative = false); //! \copydoc CPhysicalQuantity(const QString &unitString) CTime(const QString &unitString) : CPhysicalQuantity(0, CTimeUnit::nullUnit()) { this->parseFromString(unitString); } @@ -53,11 +53,19 @@ namespace BlackMisc virtual void parseFromString(const QString &time) override; //! To Qt time + //! \warning sign not considered QTime toQTime() const; //! Parts hh, mm, ss + //! \warning sign not considered QList getHrsMinSecParts() const; + //! Formatted as hh:mm:ss + QString formattedHrsMinSec() const; + + //! Formatted as hh:mm + QString formattedHrsMin() const; + }; } // namespace