From 406c477f3fc7283432bcf6522dd8d6555c7b7c1d Mon Sep 17 00:00:00 2001 From: "Gary E. Miller" Date: Thu, 8 Nov 2018 15:41:47 -0800 Subject: gpsutils: fix rounding error in unix_to_iso8601(), add/fix tests. 1541766896.999512 became "2018-11-09T12:34:56.000Z". Which sould be :57. The fractional seconds got rounded up, but the seconds did not get incremented to match. Added regression tests for unix_to_iso8601(). Reported by Peter Liu . --- gpsutils.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'gpsutils.c') diff --git a/gpsutils.c b/gpsutils.c index 3070ca59..4d276626 100644 --- a/gpsutils.c +++ b/gpsutils.c @@ -499,11 +499,9 @@ timestamp_t iso8601_to_unix(char *isotime) #endif /* __clang_analyzer__ */ } -/* *INDENT-OFF* */ -char *unix_to_iso8601(timestamp_t fixtime, - char isotime[], size_t len) /* Unix UTC time to ISO8601, no timezone adjustment */ /* example: 2007-12-11T23:38:51.033Z */ +char *unix_to_iso8601(timestamp_t fixtime, char isotime[], size_t len) { struct tm when; double integral, fractional; @@ -512,6 +510,13 @@ char *unix_to_iso8601(timestamp_t fixtime, char fractstr[10]; fractional = modf(fixtime, &integral); + /* snprintf rounding of %3f can get ugly, so pre-round */ + if ( 0.999499999 < fractional) { + /* round up */ + integral++; + /* give the fraction a nudge to ensure rounding */ + fractional += 0.0005; + } intfixtime = (time_t) integral; #ifdef HAVE_GMTIME_R (void)gmtime_r(&intfixtime, &when); @@ -531,7 +536,6 @@ char *unix_to_iso8601(timestamp_t fixtime, (void)snprintf(isotime, len, "%s%sZ",timestr, strchr(fractstr,'.')); return isotime; } -/* *INDENT-ON* */ #define Deg2Rad(n) ((n) * DEG_2_RAD) -- cgit v1.2.1