+Internal::DateTime::Type Internal::DateTime::setDateTime(QString const & s, QDateTime const & epoch)
+{
+ mEpoch = epoch;
+ return setDateTime(s);
+}
+
+Internal::DateTime::Type Internal::DateTime::setDateTime(QString const & s)
+{
+ // Detect the type of the date/time string
+ mType = getDateTimeType(s);
+ if (mType == Invalid)
+ {
+ return mType;
+ }
+
+ // Convert the string to a date/time value
+ mDateTime = strToDateTime(s, mType);
+ if (!mDateTime.isValid())
+ {
+ mType = Invalid;
+ }
+
+
+ return mType;
+}
+
+void Internal::DateTime::setEpoch(QDateTime const & epoch)
+{
+ if (!epoch.isValid())
+ {
+ return;
+ }
+
+ if (epoch != mEpoch)
+ {
+ if (mDateTime.isValid())
+ {
+ qint64 diff = mEpoch.msecsTo(epoch);
+ mDateTime = mDateTime.addMSecs(diff);
+ }
+ mEpoch = epoch;
+ }
+}
+
+Internal::DateTime::Type Internal::DateTime::getDateTimeType(QString const & s) const
+{
+ if (mRxIso->exactMatch(s))
+ {
+ return ISO;
+ }
+ else if (mRxAsd->exactMatch(s))
+ {
+ return ASD;
+ }
+ else if (mRxCUC->exactMatch(s))
+ {
+ return CUC;
+ }
+ return Invalid;
+}
+
+QDateTime Internal::DateTime::strToDateTime(QString const & s, Type type) const
+{
+ switch (type)
+ {
+ case ASD:
+ {
+ // Using the yyyy.ddd.hh.mm.ss[.zzz] format
+ QStringList tok = s.split(QChar('.'));
+ if (tok.size() < 4)
+ {
+ return QDateTime();
+ }
+
+ bool ok = false;
+ int year = tok.at(0).toInt(&ok);
+ if (!ok)
+ {
+ return QDateTime();
+ }
+ int days = tok.at(1).toInt(&ok);
+ if (!ok)
+ {
+ return QDateTime();
+ }
+ int hours = tok.at(2).toInt(&ok);
+ if (!ok)
+ {
+ return QDateTime();
+ }
+ int minutes = tok.at(3).toInt(&ok);
+ if (!ok)
+ {
+ return QDateTime();
+ }
+ int secs = 0;
+ int msecs = 0;
+ if (tok.size() > 4)
+ {
+ secs = tok.at(4).toInt(&ok);
+ if (!ok)
+ {
+ return QDateTime();
+ }
+ if (tok.size() > 5)
+ {
+ msecs = tok.at(5).toInt(&ok);
+ if (!ok)
+ {
+ return QDateTime();
+ }
+ }
+ }
+
+ QDate dt(year, 1, 1);
+ dt = dt.addDays(days - 1);
+
+ return QDateTime(dt, QTime(hours, minutes, secs, msecs), Qt::UTC);
+ break;
+ }
+ case ISO:
+ {
+ // Using the ISO format yyyy-MM-ddThh:mm:ss[.zzz]
+ QString tmp = s;
+ if (tmp.length() < 19)
+ {
+ tmp += ":00";
+ }
+ QDateTime dt = QDateTime::fromString(tmp, Qt::ISODate);
+ dt.setTimeSpec(Qt::UTC);
+ return dt;
+ break;
+ }
+ case CUC:
+ {
+ // Get the CUC coarse and fine values
+ bool ok = false;
+ int coarse = s.left(8).toLong(&ok, 16);
+ if (!ok)
+ {
+ return QDateTime();
+ }
+ int fine = 0;
+ if (s.size() == 12)
+ {
+ fine = s.mid(8, 4).toLong(&ok, 16);
+ if (!ok)
+ {
+ return QDateTime();
+ }
+ }
+
+ // Get the date/time value
+ QDateTime tm = mEpoch.addSecs(coarse);
+ tm = tm.addMSecs(rint((double(fine) / 58.0 * 885.0) / 1000.0));
+ return tm;
+
+ break;
+ }
+ default:
+ {
+ return QDateTime();
+ }
+ }
+}
+
+QString Internal::DateTime::asISOstring() const
+{
+ if (mDateTime.isValid())
+ {
+ return mDateTime.toString("yyyy-MM-ddThh:mm:ss.zzz");
+ }
+ return QString();
+}
+
+QString Internal::DateTime::asASDstring() const
+{
+ if (mDateTime.isValid())
+ {
+ return QString("%1.%2.%3.%4.%5.%6")
+ .arg(mDateTime.date().year(), 4, 10, QChar('0'))
+ .arg(mDateTime.date().dayOfYear(), 3, 10, QChar('0'))
+ .arg(mDateTime.time().hour(), 2, 10, QChar('0'))
+ .arg(mDateTime.time().minute(), 2, 10, QChar('0'))
+ .arg(mDateTime.time().second(), 2, 10, QChar('0'))
+ .arg(mDateTime.time().msec(), 3, 10, QChar('0'));
+ }
+ return QString();
+}
+
+QString Internal::DateTime::asCUChexString() const
+{
+ if (!mDateTime.isValid())
+ {
+ return QString();
+ }
+
+ // Convert to CUC coarse and fine values
+ qint64 msecs = mEpoch.msecsTo(mDateTime);
+ quint32 coarse = quint32(msecs / 1000);
+ quint32 fine = quint32(rint(1000.0 * double(msecs % 1000) * 58.0 / 885.0));
+
+ // Set the CUC hex string
+ return QString("%1%2").arg(coarse, 8, 16, QChar('0')).arg(fine, 4, 16, QChar('0'));