From 40429dd3db113c30652e8e66b2a38237f1edbf39 Mon Sep 17 00:00:00 2001 From: tsteven4 <13596209+tsteven4@users.noreply.github.com> Date: Mon, 6 Dec 2021 16:37:53 -0700 Subject: [PATCH] fix dotnet time conversion (#784) --- defs.h | 2 +- reference/dotnet.csv | 6 ++++++ reference/dotnet~csv.csv | 6 ++++++ testo.d/unitconversion.test | 13 +++++++++++++ util.cc | 18 ++++-------------- xcsv.cc | 8 +++++--- xmldoc/chapters/styles.xml | 2 +- 7 files changed, 36 insertions(+), 19 deletions(-) create mode 100644 reference/dotnet.csv create mode 100644 reference/dotnet~csv.csv diff --git a/defs.h b/defs.h index 7ee53fd09..820232e0d 100644 --- a/defs.h +++ b/defs.h @@ -1113,7 +1113,7 @@ time_t mklocaltime(struct tm* t); time_t mkgmtime(struct tm* t); bool gpsbabel_testmode(); gpsbabel::DateTime current_time(); -void dotnet_time_to_time_t(double dotnet, time_t* t, int* millisecs); +QDateTime dotnet_time_to_qdatetime(long long dotnet); const char* get_cache_icon(const Waypoint* waypointp); const char* gs_get_cachetype(geocache_type t); const char* gs_get_container(geocache_container t); diff --git a/reference/dotnet.csv b/reference/dotnet.csv new file mode 100644 index 000000000..80fda5a95 --- /dev/null +++ b/reference/dotnet.csv @@ -0,0 +1,6 @@ +0,40,105 # .net epoch midnight Jan 1, 1 +4999,40.5,105.5 # should round down +5001,40.5,105.5 # should round up +864000000000,41,106 # (60sec/min * 60min/hr * 24hr/day) / 100e-9 sec = midnight Jan 2, 1. +637739532350000000,42,107 # GMT / UTC Date Time 2021-12-01 11:00:35 + 0.0000000 second + diff --git a/reference/dotnet~csv.csv b/reference/dotnet~csv.csv new file mode 100644 index 000000000..87a80ba66 --- /dev/null +++ b/reference/dotnet~csv.csv @@ -0,0 +1,6 @@ +No,Latitude,Longitude,Name,Date,Time +1,40.000000,105.000000,"WPT001",0001/01/01,00:00:00 +2,40.500000,105.500000,"WPT002",0001/01/01,00:00:00 +3,40.500000,105.500000,"WPT003",0001/01/01,00:00:00.001 +4,41.000000,106.000000,"WPT004",0001/01/02,00:00:00 +5,42.000000,107.000000,"WPT005",2021/12/01,11:00:35 diff --git a/testo.d/unitconversion.test b/testo.d/unitconversion.test index 326d7d63f..9266da838 100644 --- a/testo.d/unitconversion.test +++ b/testo.d/unitconversion.test @@ -66,3 +66,16 @@ echo 'OFIELD PATH_DISTANCE_NAUTICAL_MILES,"","%.6e"' >> ${TMPDIR}/distance3.styl gpsbabel -t -i xcsv,style=${TMPDIR}/distance3.style -f ${REFERENCE}/distance3.csv -o xcsv,style=${TMPDIR}/distance3.style -F ${TMPDIR}/distance3~csv.csv compare ${REFERENCE}/distance3~csv.csv ${TMPDIR}/distance3~csv.csv + +echo 'DESCRIPTION dotnet test' > ${TMPDIR}/dotnet.style +echo 'EXTENSION csv' >> ${TMPDIR}/dotnet.style +echo 'DATATYPE WAYPOINT' >> ${TMPDIR}/dotnet.style +echo 'FIELD_DELIMITER COMMA' >> ${TMPDIR}/dotnet.style +echo 'RECORD_DELIMITER NEWLINE' >> ${TMPDIR}/dotnet.style +echo 'BADCHARS COMMA' >> ${TMPDIR}/dotnet.style +echo 'IFIELD NET_TIME, "","%lld"' >> ${TMPDIR}/dotnet.style +echo 'IFIELD LAT_DECIMAL,"","%.9f"' >> ${TMPDIR}/dotnet.style +echo 'IFIELD LON_DECIMAL,"","%.9f"' >> ${TMPDIR}/dotnet.style +gpsbabel -i xcsv,style=${TMPDIR}/dotnet.style -f ${REFERENCE}/dotnet.csv -o unicsv,utc=0 -F ${TMPDIR}/dotnet.csv +compare ${REFERENCE}/dotnet~csv.csv ${TMPDIR}/dotnet.csv + diff --git a/util.cc b/util.cc index 7db6af8a8..fb9921a96 100644 --- a/util.cc +++ b/util.cc @@ -765,23 +765,13 @@ current_time() * internals and since we're in the GPS biz, timestamps before 1/1/1970 aren't * that interesting to us anyway. */ -#define EPOCH_TICKS 621355968000000000.0 -void dotnet_time_to_time_t(double dotnet, time_t* t, int* millisecs) +QDateTime dotnet_time_to_qdatetime(long long dotnet) { - // TODO: replace this with better interface with normal return values - // and called via a QDateTime. - *t = (dotnet - EPOCH_TICKS) / 10000000.; -#if LATER - // TODO: work out fractional seconds. - if (millisecs) { - *millisecs = dotnet % 10000; - } -#else - (void)millisecs; -#endif + QDateTime epoch = QDateTime(QDate(1, 1, 1), QTime(0, 0, 0), Qt::UTC); + qint64 millisecs = (dotnet + 5000)/ 10000; + return epoch.addMSecs(millisecs); } - /* * Return a pointer to a constant string that is suitable for icon lookup * based on geocache attributes. The strings used are those present in diff --git a/xcsv.cc b/xcsv.cc index 048bb0a14..c3d0fc9e5 100644 --- a/xcsv.cc +++ b/xcsv.cc @@ -641,9 +641,11 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle: wpt->SetCreationTime(xml_parse_time(s)); break; case XcsvStyle::XT_NET_TIME: { - fatal("XT_NET_TIME can't have possibly ever worked."); -// time_t tt = wpt->GetCreationTime(); -// dotnet_time_to_time_t(atof(s), &tt, &wpt->microseconds); + bool ok; + wpt->SetCreationTime(dotnet_time_to_qdatetime(value.toLongLong(&ok))); + if (!ok) { + warning("parse of string '%s' on line number %d as NET_TIME failed.\n", s, line_no); + } } break; case XcsvStyle::XT_GEOCACHE_LAST_FOUND: diff --git a/xmldoc/chapters/styles.xml b/xmldoc/chapters/styles.xml index f18b910d8..49c21cf02 100644 --- a/xmldoc/chapters/styles.xml +++ b/xmldoc/chapters/styles.xml @@ -928,7 +928,7 @@ longitude) example: - IFIELD NET_TIME,"","%f" + IFIELD NET_TIME,"","%lld"