From 23e61c6c95437c816d311057b1f0dc21645a1bcc Mon Sep 17 00:00:00 2001 From: eelke Date: Sun, 6 Feb 2022 14:15:16 +0100 Subject: [PATCH] Fix broken unittest. Was probably broken by a change in Qt. Now using custom parser. (I also tested a regex based parser but that was more then 80 times slower) --- pgsql/Pgsql_Value.cpp | 47 +++++++++++++++++++++++++++++++++- tests/PgsqlTests/tst_Value.cpp | 4 +-- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/pgsql/Pgsql_Value.cpp b/pgsql/Pgsql_Value.cpp index 4a740ed..d0df733 100644 --- a/pgsql/Pgsql_Value.cpp +++ b/pgsql/Pgsql_Value.cpp @@ -36,7 +36,52 @@ Value::operator QDate() const Value::operator QTime() const { - return QTime::fromString(asQString(), Qt::ISODateWithMs); + // as values are expected to be coming straight out of postgresql + // we will not validate everything + char* pos; + int hours = std::strtol(m_val, &pos, 10); + if (*pos == ':') + ++pos; + else + throw std::runtime_error("Unpexted character after hour in input"); + int minutes = std::strtol(pos, &pos, 10); + if (*pos == ':') + ++pos; + else + throw std::runtime_error("Unpexted character after minutes in input"); + int seconds = std::strtol(pos, &pos, 10); + int millis = 0; + if (*pos == '.') + { + const char *start = ++pos; + millis = std::strtol(pos, &pos, 10); + int length = pos - start; + switch (length) { + case 0: break; // should be zero anyway so no reason to multiply by 1000 + case 1: millis *= 100; break; + case 2: millis *= 10; break; + case 3: break; + case 4: millis = (millis + 5) / 10; break; + case 5: millis = (millis + 50) / 100; break; + case 6: millis = (millis + 500) / 1000; break; + default: + throw std::runtime_error("Unpexted number of digits in microsecond field"); + } + } + int tzhours = 0, tzminutes = 0; + if (*pos == '+' || *pos == '-') + { + ++pos; + tzhours = std::strtol(pos, &pos, 10); + if (*pos == ':') + { + tzminutes = std::strtol(pos, &pos, 10); + } + // TODO QTime does not support timezones (and rightly so as they are meaningless without a date) + // the postgresql documentation actually agrees with this but supports timezones to not break + // compatability with older verions + } + return QTime(hours, minutes, seconds, millis); } diff --git a/tests/PgsqlTests/tst_Value.cpp b/tests/PgsqlTests/tst_Value.cpp index dd66495..6642b8e 100644 --- a/tests/PgsqlTests/tst_Value.cpp +++ b/tests/PgsqlTests/tst_Value.cpp @@ -49,9 +49,9 @@ TEST(Pgsql_Value, test_QTime) TEST(Pgsql_Value, test_QTimeMS) { - Pgsql::Value v("09:38:17.339817+02", timetz_oid); + Pgsql::Value v("09:38:17.339+02:00", timetz_oid); QTime t = v; - ASSERT_EQ(t, QTime(9, 38, 17, 340)); + ASSERT_EQ(t, QTime(9, 38, 17, 339)); }