[PATCH] Attempt to fix a crash on DM4 Windows import

Miika Turkia miika.turkia at gmail.com
Wed May 8 23:50:31 PDT 2013


It appears that Windows returns NULL when converting DM4 database's date
stamps to local time. (This is due to DM4 using time since year 1, not
epoch and Windows doing "sanity checking" on the time.)

This patch moves the conversion of time format directly to database
query so the localtime should function on Windows. It will also fail
gracefully in case of NULL (with error message: failed to parse input).

Signed-off-by: Miika Turkia <miika.turkia at gmail.com>
---
 parse-xml.c |   25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/parse-xml.c b/parse-xml.c
index f850e9d..5a13934 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -1707,14 +1707,23 @@ extern int dm4_dive(void *param, int columns, char **data, char **column)
 	dive_start();
 	cur_dive->number = atoi(data[0]);
 
-	/* Suunto saves time in 100 nano seconds, we'll need the time in
-	 * seconds.
-	 */
-	when = (time_t)(atol(data[1]) / 10000000);
+	when = (time_t)(atol(data[1]));
 	tm = localtime(&when);
 
-	/* Suunto starts counting time in year 1, we need epoch */
-	tm->tm_year -= 1969;
+	/* Bailing out if localtime returns NULL */
+	if (!tm)
+		return -1;
+
+	/*
+	 * I am not sure about the timezones when it comes to Suunto
+	 * DM4. However, with a sample on GMT+2 and another in GMT+1
+	 * this code seems to work.
+	 * Remaining question is, how to handle daylight savings.
+	 * (Samples I have are contradicting each other...)
+	 */
+	tm->tm_hour += tm->tm_gmtoff / 3600;
+	tm->tm_min += tm->tm_gmtoff % 3600;
+
 	cur_dive->when = mktime(tm);
 	if (data[2])
 		utf8_string(data[2], &cur_dive->notes);
@@ -1827,7 +1836,9 @@ int parse_dm4_buffer(const char *url, const char *buffer, int size,
 	sqlite3 *handle;
 	target_table = table;
 
-	char get_dives[] = "select D.DiveId,StartTime,Note,Duration,SourceSerialNumber,Source,MaxDepth,SampleInterval,StartTemperature,BottomTemperature,D.StartPressure,D.EndPressure,Size,CylinderWorkPressure,SurfacePressure,DiveTime,SampleInterval,ProfileBlob,TemperatureBlob,PressureBlob,Oxygen,Helium,MIX.StartPressure,MIX.EndPressure FROM Dive AS D JOIN DiveMixture AS MIX ON D.DiveId=MIX.DiveId";
+	/* StartTime is converted from Suunto's nano seconds to standard
+	 * time. We also need epoch, not seconds since year 1. */
+	char get_dives[] = "select D.DiveId,StartTime/10000000-62135604000,Note,Duration,SourceSerialNumber,Source,MaxDepth,SampleInterval,StartTemperature,BottomTemperature,D.StartPressure,D.EndPressure,Size,CylinderWorkPressure,SurfacePressure,DiveTime,SampleInterval,ProfileBlob,TemperatureBlob,PressureBlob,Oxygen,Helium,MIX.StartPressure,MIX.EndPressure FROM Dive AS D JOIN DiveMixture AS MIX ON D.DiveId=MIX.DiveId";
 
 	retval = sqlite3_open(url,&handle);
 
-- 
1.7.9.5



More information about the subsurface mailing list