diff options
author | Gary E. Miller <gem@rellim.com> | 2018-11-08 15:41:47 -0800 |
---|---|---|
committer | Gary E. Miller <gem@rellim.com> | 2018-11-08 15:41:47 -0800 |
commit | 406c477f3fc7283432bcf6522dd8d6555c7b7c1d (patch) | |
tree | e59da1660680052a0b5c475aaf12ba7a365792b7 /gpsutils.c | |
parent | 613fa2733f22586899bbd64df06804cb1932380c (diff) | |
download | gpsd-406c477f3fc7283432bcf6522dd8d6555c7b7c1d.tar.gz |
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 <greendice@me.com>.
Diffstat (limited to 'gpsutils.c')
-rw-r--r-- | gpsutils.c | 12 |
1 files changed, 8 insertions, 4 deletions
@@ -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) |