OpenTracksApp / OpenTracks

OpenTracks is a sport tracking application that completely respects your privacy.
https://OpenTracksApp.com
Apache License 2.0
1.07k stars 190 forks source link

Import of track data from Gadgetbridge gets recorded in UTC time #2014

Open prurigro opened 1 week ago

prurigro commented 1 week ago

Describe the bug

Importing a recorded activity from Gadgetbridge causes OpenTracks to store it without converting the time from UTC to the local timezone. The metadata <time></time> in the exported gpx is incorrectly set to the export time and lacks a Z at the end, but OpenTracks appears to use the first trkpt <time></time>, which does have the correct UTC time with a Z at the end (eg: <time>2024-11-05T04:09:10Z</time>).

Here's the connected issue @ Gadgetbridge: https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/4299

To Reproduce

  1. Record an activity using a Gadgetbridge-connected device
  2. Go into Gadgetbridge and select the "Your activity tracks" option for the device
  3. Sync activities
  4. Select the activity you recorded
  5. Click the share button and select "Share GPS Track"
  6. Share to OpenTracks
  7. Observe the imported track showing the non-timezone-corrected time

Technical information

Thanks!

dennisguse commented 1 week ago

Related #301.

Don't recall any details (after four years).

dennisguse commented 1 week ago

Relevant code is in KmlTrackImporter. IIRC, KML is using XSD:DATETIME and this allows for time offsets. However, it is neither well documented and often not implemented. As you observed, OpenTracks uses the first encountered time offset (in a when) for the track offset. All times are then stored in UTC.

dennisguse commented 1 week ago

And here is the KML 2.3 spec: https://docs.ogc.org/is/12-007r2/12-007r2.html

Happy digging ;)

joserebelo commented 1 week ago

Gadgetbridge shares the track as gpx, not kml. The timestamps are formated as ISO8601, in UTC, following the gpx and xml specs.

dennisguse commented 1 week ago

Then the relevant code is here: https://github.com/OpenTracksApp/OpenTracks/blob/main/src%2Fmain%2Fjava%2Fde%2Fdennisguse%2Fopentracks%2Fio%2Ffile%2Fimporter%2FGpxTrackImporter.java#L278

OpenTracks is not using the gpx.time at all - Only the time for each trackpoint and then using the zone offset of the first one for all.

dennisguse commented 1 week ago

And gpx.time is actually the creation timestamp of the file according to: https://www.topografix.com/GPX/1/1/#element_gpx

prurigro commented 1 week ago

Is it possible that gpx.time (I assume you mean the one in metadata) not having a timezone is the reason the timezone in the initial trackpoint isn't getting read in?

dennisguse commented 1 week ago

Possibly :)

The XML parser code is ancient.

prurigro commented 1 week ago

So I manually edited a gpx that was importing with the wrong time and set the metadata

I also noticed that the date for an imported gpx looks like Tuesday, November 5, 2024 at 4:09:10 a.m. Z <- that Z at the end is interesting. In OpenTracks-created events, it shows -04:00 where the Z is in the imported ones.

dennisguse commented 1 week ago

@prurigro can you share a trimmed down GPX example and your expectation?

prurigro commented 1 week ago

Hey for sure- this isn't trimmed down, hopefully that's OK. It's a direct export from gadgetbridge, but keep in mind that I've tried editing the metadata

All you should need to do to see the issue is gunzip it (github won't let me upload a gpx without gzipping it), then share the gpx to OpenTracks and have it import it.

The activity took place on Sunday, November 3rd at 11:33am, but it will appear in the OpenTracks list showing 16:33 +00, and if you open it up, it will show Sunday, November 3, 2024 at 4:33:34 p.m. Z.

ACTIVITY_2024-11-03_11-33-34_334.gpx.gz

dennisguse commented 1 week ago

Thanks.

However, I don't have a computer at hand (only a phone). Would you be able to just share the relevant parts as text aka the minimal GPX(likely only one trkpt) that shows the problem?

prurigro commented 1 week ago

Ahh that makes sense- OK, I've trimmed it down to a single trackpoint and tested to confirm that it still has the same issue:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gpxtpx="https://www8.garmin.com/xmlschemas/TrackPointExtensionv2.xsd" xmlns="http://www.topografix.com/GPX/1/1" xmlns:opentracks="http://opentracksapp.com/xmlschemas/v1" version="1.1" creator="nodomain.freeyourgadget.gadgetbridge.GBApplication 0.82.0-126102aa0" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
  <metadata>
    <name>Hike</name>
    <time>2024-11-07T17:16:20-05:00</time>
  </metadata>
  <trk>
    <extensions>
      <opentracks:trackid>063c3c87-99b1-4e0d-af1f-275a7f34a25f</opentracks:trackid>
    </extensions>
    <trkseg>
      <trkpt lon="-75.813630" lat="45.287151">
        <ele>110.600000</ele>
        <time>2024-11-03T16:33:34Z</time>
        <extensions>
          <gpxtpx:TrackPointExtension>
            <gpxtpx:hr>99</gpxtpx:hr>
            <gpxtpx:cad>0</gpxtpx:cad>
            <gpxtpx:speed>0.000000</gpxtpx:speed>
          </gpxtpx:TrackPointExtension>
        </extensions>
      </trkpt>
    </trkseg>
  </trk>
</gpx>
dennisguse commented 1 week ago

Okay...

GPX 1.1 states:

IIRC OpenTracks will use the offset of the first wptType.time (similar to KML), but this should always be zero. @prurigro that's what your test shows, right?

So, a solution may be that we take the offset from metadataType.time (and ignore the actual timestamp)?

prurigro commented 1 week ago

Hmm, this is a bit more complicated than I'd initially thought. I just checked to see how osmand's exported gpx metadata looks, and it uses UTC:

<metadata>
    <name>2024-11-08_11-46_Fri</name>
    <time>2024-11-08T16:46:55Z</time>
</metadata>

So that solution wouldn't work for Osmand (and presumably others), and @joserebelo is planning on fixing the metadata time in Gadgetbridge so it complies with the standard too.

Using the current local timezone doesn't necessarily make sense either because of daylight savings, or maybe you imported a track from a trip once you're back home. In theory GPS could be used to determine the timezone (and the date to see whether it should be in daylight time or not), but that seems like a solution that would require a LOT of work if there isn't already a library for it, especially with certain places observing daylight savings and other places not... It's a shame there's no standard field to add the timezone to the metadata.

What if OpenTracks simply allowed editing the timezone attached to a given track? At that point you could import with UTC, or defaulting to the current local timezone might be better as it would cover most cases, and then the user could edit the ones that were incorrect?

dennisguse commented 6 days ago

:)

OpenTracks only considers the timezone offset as handling all the wonderful timezone details is too complicated for this case. Back then I also wanted to use the timezone, but luckily I was convinced (by @pstorch) that it is incredibly complicated to get right.

Adding a UI to change timezone offset is doable. I guess the activity that needs to be adjusted is TrackEditDetail - best guess adding a proper UI element + some data handling (storage and update should already be handled correctly).

@prurigro do you have the time for a PR?

prurigro commented 6 days ago

The next month or so is looking pretty tight, but I can try my hand at figuring out what's going on after that if this is still open when things calm down a bit :)