From 8e19dfebe643e4219c7951d8d1f372003a7de000 Mon Sep 17 00:00:00 2001 From: Justin King <56605940+justinswork@users.noreply.github.com> Date: Tue, 19 Nov 2024 23:09:29 -0500 Subject: [PATCH] Fix RMC FixTime parsing that can lose sub-second precision with doubles (#117) * Extract local variables for the parameters of DateTimeOffset * Add seconds to FixTime as Ticks in order to preserve sub-second precision that can get lost by using doubles --------- Co-authored-by: Justin King --- src/NmeaParser/Nmea/Rmc.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/NmeaParser/Nmea/Rmc.cs b/src/NmeaParser/Nmea/Rmc.cs index f9a8771..d0bf862 100644 --- a/src/NmeaParser/Nmea/Rmc.cs +++ b/src/NmeaParser/Nmea/Rmc.cs @@ -42,12 +42,15 @@ namespace NmeaParser.Messages if (message[8].Length == 6 && message[0].Length >= 6) { - FixTime = new DateTimeOffset(int.Parse(message[8].Substring(4, 2), CultureInfo.InvariantCulture) + 2000, - int.Parse(message[8].Substring(2, 2), CultureInfo.InvariantCulture), - int.Parse(message[8].Substring(0, 2), CultureInfo.InvariantCulture), - int.Parse(message[0].Substring(0, 2), CultureInfo.InvariantCulture), - int.Parse(message[0].Substring(2, 2), CultureInfo.InvariantCulture), - 0, TimeSpan.Zero).AddSeconds(double.Parse(message[0].Substring(4), CultureInfo.InvariantCulture)); + var year = int.Parse(message[8].Substring(4, 2), CultureInfo.InvariantCulture) + 2000; + var month = int.Parse(message[8].Substring(2, 2), CultureInfo.InvariantCulture); + var day = int.Parse(message[8].Substring(0, 2), CultureInfo.InvariantCulture); + var hour = int.Parse(message[0].Substring(0, 2), CultureInfo.InvariantCulture); + var minute = int.Parse(message[0].Substring(2, 2), CultureInfo.InvariantCulture); + var secondTicks = (long)(decimal.Parse(message[0].Substring(4), CultureInfo.InvariantCulture) * TimeSpan.TicksPerSecond); + + FixTime = new DateTimeOffset(year, month, day, hour, minute, 0, TimeSpan.Zero) + .AddTicks(secondTicks); } Active = (message[1] == "A"); Latitude = NmeaMessage.StringToLatitude(message[2], message[3]);