mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
GPX: Fix parsing of timestamps without timezone
Although these are non-conforming, there are a lot of gpx files online that do not contain a timezone and fail to be parsed.
This commit is contained in:
@@ -160,6 +160,10 @@ public class GpxParser {
|
|||||||
if (text == null || text.length() < 1) {
|
if (text == null || text.length() < 1) {
|
||||||
return defaultDate;
|
return defaultDate;
|
||||||
}
|
}
|
||||||
|
// If no timezone indicator is present, assume UTC
|
||||||
|
if (!text.endsWith("Z") && !text.contains("+") && !(text.length() > 19 && text.charAt(19) == '-')) {
|
||||||
|
return ISO8601Utils.parse(text + "Z", new ParsePosition(0));
|
||||||
|
}
|
||||||
return ISO8601Utils.parse(text, new ParsePosition(0));
|
return ISO8601Utils.parse(text, new ParsePosition(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -201,6 +201,31 @@ public class GPXParserTest extends TestBase {
|
|||||||
Assert.assertEquals(trackpoint.getVdop(), activityPoint.getLocation().getVdop(), 0.0);
|
Assert.assertEquals(trackpoint.getVdop(), activityPoint.getLocation().getVdop(), 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldParseDatetimeVariants() throws IOException, GpxParseException {
|
||||||
|
// Validates parsing of timestamps with no timezone (treated as UTC), explicit UTC (Z),
|
||||||
|
// positive offset, and negative offset.
|
||||||
|
try (final InputStream inputStream = getClass().getResourceAsStream("/gpx-parser-test-datetime.gpx")) {
|
||||||
|
final GpxParser gpxParser = new GpxParser(inputStream);
|
||||||
|
final GpxFile gpxFile = gpxParser.getGpxFile();
|
||||||
|
|
||||||
|
// Metadata time: No timezone indicator: should be treated as UTC
|
||||||
|
Assert.assertEquals(Date.from(Instant.parse("2026-05-23T19:31:00Z")), gpxFile.getTime());
|
||||||
|
|
||||||
|
final List<GpxTrackPoint> points = gpxFile.getPoints();
|
||||||
|
Assert.assertEquals(4, points.size());
|
||||||
|
|
||||||
|
// No timezone: treated as UTC
|
||||||
|
Assert.assertEquals(Date.from(Instant.parse("2026-05-23T19:31:24Z")), points.get(0).getTime());
|
||||||
|
// Explicit UTC (Z)
|
||||||
|
Assert.assertEquals(Date.from(Instant.parse("2026-05-23T19:32:00Z")), points.get(1).getTime());
|
||||||
|
// Positive offset (+02:00): 21:33 local = 19:33 UTC
|
||||||
|
Assert.assertEquals(Date.from(Instant.parse("2026-05-23T19:33:00Z")), points.get(2).getTime());
|
||||||
|
// Negative offset (-07:00): 12:34 local = 19:34 UTC
|
||||||
|
Assert.assertEquals(Date.from(Instant.parse("2026-05-23T19:34:00Z")), points.get(3).getTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// test import of old GPX v1.0
|
// test import of old GPX v1.0
|
||||||
@Test
|
@Test
|
||||||
public void TestGpxImportOld() throws Exception {
|
public void TestGpxImportOld() throws Exception {
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
|
||||||
|
<gpx version="1.1" creator="NonConformingDevice"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
||||||
|
xmlns="http://www.topografix.com/GPX/1/1">
|
||||||
|
<metadata>
|
||||||
|
<name>Test Timezone Variants</name>
|
||||||
|
<!-- No timezone indicator: should be treated as UTC -->
|
||||||
|
<time>2026-05-23T19:31:00</time>
|
||||||
|
</metadata>
|
||||||
|
<trk>
|
||||||
|
<trkseg>
|
||||||
|
<!-- No timezone: treated as UTC -->
|
||||||
|
<trkpt lon="9.7393798828125" lat="47.5048828125">
|
||||||
|
<ele>440.0</ele>
|
||||||
|
<time>2026-05-23T19:31:24</time>
|
||||||
|
</trkpt>
|
||||||
|
<!-- Explicit UTC (Z) -->
|
||||||
|
<trkpt lon="9.7394798828125" lat="47.5058828125">
|
||||||
|
<ele>441.0</ele>
|
||||||
|
<time>2026-05-23T19:32:00Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<!-- Positive offset (+02:00): 21:33 local = 19:33 UTC -->
|
||||||
|
<trkpt lon="9.7395798828125" lat="47.5068828125">
|
||||||
|
<ele>442.0</ele>
|
||||||
|
<time>2026-05-23T21:33:00+02:00</time>
|
||||||
|
</trkpt>
|
||||||
|
<!-- Negative offset (-07:00): 12:34 local = 19:34 UTC -->
|
||||||
|
<trkpt lon="9.7396798828125" lat="47.5078828125">
|
||||||
|
<ele>443.0</ele>
|
||||||
|
<time>2026-05-23T12:34:00-07:00</time>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
</gpx>
|
||||||
Reference in New Issue
Block a user