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"