Ref T308, using an optimized (faster) function for YYYYmmdd string parsing

Ref T309, found that QDateTime::fromString returns a QDateTime object with local timestamp. Using a optimized version returns UTC objects now.

- The bug was found writing a unit test for Ref T308
- Slack: https://swift-project.slack.com/archives/G7GD2UP9C/p1534848725000100
This commit is contained in:
Klaus Basan
2018-08-21 15:19:16 +02:00
parent d3c3fe2566
commit 183280fa75
13 changed files with 167 additions and 61 deletions

View File

@@ -18,6 +18,7 @@
#include "blackmisc/stringutils.h"
#include <QTest>
#include <QTime>
using namespace BlackMisc;
@@ -48,7 +49,7 @@ namespace BlackMiscTest
void CTestStringUtils::testSplit()
{
QString s = "line one\nline two\r\nline three\n";
const QString s = "line one\nline two\r\nline three\n";
QStringList lines = splitLines(s);
QVERIFY2(lines.size() == 3, "Test split string into lines: correct number of lines");
QVERIFY2(lines[0] == "line one", "Test split string into lines: correct first line");
@@ -56,6 +57,76 @@ namespace BlackMiscTest
QVERIFY2(lines[2] == "line three", "Test split string into lines: correct third line");
}
void CTestStringUtils::testTimestampParsing()
{
const QStringList dts(
{
"2018-01-01 11:11:11",
"2012-05-09 03:04:05.777",
"2012-05-09 00:00:00.000",
"2015-12-31 03:04:05",
"1999-12-31 23:59:59.999",
"1975-01-01 14:13:17",
"1982-05-09 03:01:05.123",
"2000-05-02 00:04:00.000",
"2002-12-31 03:34:33",
"1992-11-01 21:59:29.999"
});
const int size = QString("yyyyMMddHHmmss").size();
for (const QString &dt : dts)
{
const QString c = removeDateTimeSeparators(dt);
const QDateTime dt1 = parseDateTimeStringOptimized(c);
const QDateTime dt2 = (c.length() == size) ?
fromStringUtc(c, "yyyyMMddHHmmss") :
fromStringUtc(c, "yyyyMMddHHmmsszzz");
QDateTime dt3 = (c.length() == size) ?
QDateTime::fromString(c, "yyyyMMddHHmmss") :
QDateTime::fromString(c, "yyyyMMddHHmmsszzz");
dt3.setUtcOffset(0);
const qint64 ms1 = dt1.toMSecsSinceEpoch();
const qint64 ms2 = dt2.toMSecsSinceEpoch();
const qint64 delta = ms1 - ms2;
QVERIFY2(dt1 == dt2, "Expect same results of QDateTime");
QVERIFY2(dt1 == dt3, "Expect same results of QDateTime");
QVERIFY2(delta == 0, "Expect same results timestamp");
}
// performance
int constexpr Loops = 10000;
QTime time;
time.start();
for (int i = 0; i < Loops; i++)
{
for (const QString &dt : dts)
{
const QString c = removeDateTimeSeparators(dt);
const QDateTime dateTime = parseDateTimeStringOptimized(c);
parseDateTimeStringOptimized(c);
Q_UNUSED(dateTime); // avoid optimizing out of call
}
}
const int elapsedOptimized = time.restart();
for (int i = 0; i < Loops; i++)
{
for (const QString &dt : dts)
{
const QString c = removeDateTimeSeparators(dt);
const QDateTime dateTime = (c.length() == size) ?
fromStringUtc(c, "yyyyMMddHHmmss") :
fromStringUtc(c, "yyyyMMddHHmmsszzz");
Q_UNUSED(dateTime); // avoid optimizing out of call
}
}
const int elapsedQt = time.restart();
qDebug() << "Parsing date/time, optimized" << elapsedOptimized << "vs. QDateTime: " << elapsedQt;
QVERIFY2(elapsedOptimized < elapsedQt, "Expect optimized being faster as QDateTim::fromString");
}
}
//! \endcond

View File

@@ -21,7 +21,6 @@
namespace BlackMiscTest
{
//! Testing string utilities
class CTestStringUtils : public QObject
{
@@ -36,8 +35,8 @@ namespace BlackMiscTest
void testContains();
void testIndexOf();
void testSplit();
void testTimestampParsing();
};
}
//! \endcond