Index: trunk/src/org/openstreetmap/josm/io/nmea/NmeaReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/nmea/NmeaReader.java	(revision 14062)
+++ trunk/src/org/openstreetmap/josm/io/nmea/NmeaReader.java	(revision 14067)
@@ -15,5 +15,6 @@
 import java.util.Locale;
 import java.util.Objects;
-import java.util.Optional;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.openstreetmap.josm.data.coor.LatLon;
@@ -45,4 +46,9 @@
 public class NmeaReader implements IGpxReader {
 
+    /**
+     * Course Over Ground and Ground Speed.
+     * <p>
+     * The actual course and speed relative to the ground
+     */
     enum VTG {
         COURSE(1), COURSE_REF(2), // true course
@@ -59,4 +65,12 @@
     }
 
+    /**
+     * Recommended Minimum Specific GNSS Data.
+     * <p>
+     * Time, date, position, course and speed data provided by a GNSS navigation receiver.
+     * This sentence is transmitted at intervals not exceeding 2-seconds.
+     * RMC is the recommended minimum data to be provided by a GNSS receiver.
+     * All data fields must be provided, null fields used only when data is temporarily unavailable.
+     */
     enum RMC {
         TIME(1),
@@ -81,4 +95,9 @@
     }
 
+    /**
+     * Global Positioning System Fix Data.
+     * <p>
+     * Time, position and fix related data for a GPS receiver.
+     */
     enum GGA {
         TIME(1), LATITUDE(2), LATITUDE_NAME(3), LONGITUDE(4), LONGITUDE_NAME(5),
@@ -99,4 +118,16 @@
     }
 
+    /**
+     * GNSS DOP and Active Satellites.
+     * <p>
+     * GNSS receiver operating mode, satellites used in the navigation solution reported by the GGA or GNS sentence,
+     * and DOP values.
+     * If only GPS, GLONASS, etc. is used for the reported position solution the talker ID is GP, GL, etc.
+     * and the DOP values pertain to the individual system. If GPS, GLONASS, etc. are combined to obtain the
+     * reported position solution multiple GSA sentences are produced, one with the GPS satellites, another with
+     * the GLONASS satellites, etc. Each of these GSA sentences shall have talker ID GN, to indicate that the
+     * satellites are used in a combined solution and each shall have the PDOP, HDOP and VDOP for the
+     * combined satellites used in the position.
+     */
     enum GSA {
         AUTOMATIC(1),
@@ -115,4 +146,9 @@
     }
 
+    /**
+     * Geographic Position - Latitude/Longitude.
+     * <p>
+     * Latitude and Longitude of vessel position, time of position fix and status.
+     */
     enum GLL {
         LATITUDE(1), LATITUDE_NS(2), // Latitude, NS
@@ -135,13 +171,25 @@
     GpxData data;
 
+    private static final Pattern DATE_TIME_PATTERN = Pattern.compile("(\\d{12})(\\.\\d+)?");
+
     private final SimpleDateFormat rmcTimeFmt = new SimpleDateFormat("ddMMyyHHmmss.SSS", Locale.ENGLISH);
-    private final SimpleDateFormat rmcTimeFmtStd = new SimpleDateFormat("ddMMyyHHmmss", Locale.ENGLISH);
 
     private Date readTime(String p) throws IllegalDataException {
-        Date d = Optional.ofNullable(rmcTimeFmt.parse(p, new ParsePosition(0)))
-                .orElseGet(() -> rmcTimeFmtStd.parse(p, new ParsePosition(0)));
-        if (d == null)
-            throw new IllegalDataException("Date is malformed: '" + p + "'");
-        return d;
+        // NMEA defines time with "a variable number of digits for decimal-fraction of seconds"
+        // This variable decimal fraction cannot be parsed by SimpleDateFormat
+        Matcher m = DATE_TIME_PATTERN.matcher(p);
+        if (m.matches()) {
+            String date = m.group(1);
+            double milliseconds = 0d;
+            if (m.groupCount() > 1 && m.group(2) != null) {
+                milliseconds = 1000d * Double.parseDouble("0" + m.group(2));
+            }
+            // Add milliseconds on three digits to match SimpleDateFormat pattern
+            date += String.format(".%03d", (int) milliseconds);
+            Date d = rmcTimeFmt.parse(date, new ParsePosition(0));
+            if (d != null)
+                return d;
+        }
+        throw new IllegalDataException("Date is malformed: '" + p + "'");
     }
 
@@ -177,5 +225,4 @@
         this.source = Objects.requireNonNull(source);
         rmcTimeFmt.setTimeZone(DateUtils.UTC);
-        rmcTimeFmtStd.setTimeZone(DateUtils.UTC);
     }
 
