Repository navigation
Fix FIT epoch timezone bug and preserve sensor data for GPS-less activities - #4
Merged
Merged
Conversation
…vities - FITTypes: pin FIT.epoch to timeIntervalSince1970(631065600). The epoch used to be built from DateComponents via a Calendar with no pinned time zone, so it resolved to midnight in the user's local zone instead of UTC. Under PST the epoch became 1989-12-31 08:00:00Z, shifting every decoded timestamp by the local UTC offset and producing bogus activity dates. - FITCoder: preserve per-record sensor data (heart rate, cadence, power, speed, altitude, timestamps) for indoor/trainer activities that contain no GPS positions. Records without position_lat/position_long used to be dropped entirely, yielding an empty FeatureCollection. The track is now emitted as an empty MultiLineString with the sensor arrays intact, and the encoder writes such sensor-only records with at least one lap so they round-trip cleanly. - FITDecoder: wrap array-element Data slice in Data(...) so decodeSingle receives a standalone Data value. - Tests: add FITEpochTests (epoch is exactly 1989-12-31T00:00:00Z) and IndoorActivityTests (GPS-less FIT round-trips with HR/cadence/power/ timestamps preserved).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two correctness bugs surfaced while auditing real-world FIT files.
1. FIT epoch was timezone-dependent (garmin epoch issue)
FIT.epochwas built fromDateComponentsvia aCalendar(identifier: .gregorian)with no time zone pinned, so it resolved to midnight in the user's local zone instead of UTC. On a PST machine the epoch became1989-12-31 08:00:00Z, eight hours ahead of the spec, shifting every decoded FIT timestamp by the local UTC offset.Fixed by pinning
FIT.epoch = Date(timeIntervalSince1970: 631065600)(exactly1989-12-31T00:00:00Zper the Garmin FIT profile).FITEpochTestslocks this down and verifiesdateFromTimestampagainst an independently computed UTC date.2. Indoor/trainer activities lost all sensor data
Activities whose
recordmessages carry heart rate, cadence, power, speed, altitude and timestamps but no GPS positions (e.g. indoor bike trainer workouts) produced an emptyFeatureCollection.FITCoder.convertToGeoJSONdropped every record lackingposition_lat/position_long, discarding all per-point sensor data.FITCodernow keeps every record's sensor arrays indexed across all records, and emits an emptyMultiLineStringas the track geometry when no record has GPS. The encoder was updated to write sensor-only records (with at least one lap) so indoor activities round-trip cleanly.IndoorActivityTestsverifies a GPS-less FIT preserves HR/cadence/power/timestamps through read → write → read.