From 6077776880b113f5ea7f978ee244f3dc5958337b Mon Sep 17 00:00:00 2001 From: Sascha Zepter <60738409+saschazepter@users.noreply.github.com> Date: Tue, 24 Sep 2024 22:46:52 +0200 Subject: [PATCH] Allow different timestamp formats in Google exports to be parsed --- app/services/google_maps/records_parser.rb | 17 +++++++++++++- .../google_maps/semantic_history_parser.rb | 23 +++++++++++++++---- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/app/services/google_maps/records_parser.rb b/app/services/google_maps/records_parser.rb index 92e62600..2e97a885 100644 --- a/app/services/google_maps/records_parser.rb +++ b/app/services/google_maps/records_parser.rb @@ -35,10 +35,25 @@ class GoogleMaps::RecordsParser { latitude: json['latitudeE7'].to_f / 10**7, longitude: json['longitudeE7'].to_f / 10**7, - timestamp: DateTime.parse(json['timestamp']).to_i, + timestamp: parse_timestamp(json['timestamp'] || json['timestampMs']), altitude: json['altitude'], velocity: json['velocity'], raw_data: json } end + + def parse_timestamp(timestamp) + begin + # if the timestamp is in ISO 8601 format, try to parse it + DateTime.parse(timestamp).to_time.to_i + rescue + if timestamp.to_s.length > 10 + # If the timestamp is in milliseconds, convert to seconds + timestamp.to_i / 1000 + else + # If the timestamp is in seconds, return it without change + timestamp.to_i + end + end + end end diff --git a/app/services/google_maps/semantic_history_parser.rb b/app/services/google_maps/semantic_history_parser.rb index 4231c965..dc0583c0 100644 --- a/app/services/google_maps/semantic_history_parser.rb +++ b/app/services/google_maps/semantic_history_parser.rb @@ -44,7 +44,7 @@ class GoogleMaps::SemanticHistoryParser { latitude: waypoint['latE7'].to_f / 10**7, longitude: waypoint['lngE7'].to_f / 10**7, - timestamp: DateTime.parse(timeline_object['activitySegment']['duration']['startTimestamp']).to_i, + timestamp: parse_timestamp(timeline_object['activitySegment']['duration']['startTimestamp'] || timeline_object['activitySegment']['duration']['startTimestampMs']), raw_data: timeline_object } end @@ -52,7 +52,7 @@ class GoogleMaps::SemanticHistoryParser { latitude: timeline_object['activitySegment']['startLocation']['latitudeE7'].to_f / 10**7, longitude: timeline_object['activitySegment']['startLocation']['longitudeE7'].to_f / 10**7, - timestamp: DateTime.parse(timeline_object['activitySegment']['duration']['startTimestamp']), + timestamp: parse_timestamp(timeline_object['activitySegment']['duration']['startTimestamp'] || timeline_object['activitySegment']['duration']['startTimestampMs']), raw_data: timeline_object } end @@ -62,7 +62,7 @@ class GoogleMaps::SemanticHistoryParser { latitude: timeline_object['placeVisit']['location']['latitudeE7'].to_f / 10**7, longitude: timeline_object['placeVisit']['location']['longitudeE7'].to_f / 10**7, - timestamp: DateTime.parse(timeline_object['placeVisit']['duration']['startTimestamp']), + timestamp: parse_timestamp(timeline_object['placeVisit']['duration']['startTimestamp'] || timeline_object['placeVisit']['duration']['startTimestampMs']), raw_data: timeline_object } elsif timeline_object['placeVisit']['otherCandidateLocations'].any? @@ -73,7 +73,7 @@ class GoogleMaps::SemanticHistoryParser { latitude: point['latitudeE7'].to_f / 10**7, longitude: point['longitudeE7'].to_f / 10**7, - timestamp: DateTime.parse(timeline_object['placeVisit']['duration']['startTimestamp']), + timestamp: parse_timestamp(timeline_object['placeVisit']['duration']['startTimestamp'] || timeline_object['placeVisit']['duration']['startTimestampMs']), raw_data: timeline_object } else @@ -82,4 +82,19 @@ class GoogleMaps::SemanticHistoryParser end end.reject(&:blank?) end + + def parse_timestamp(timestamp) + begin + # if the timestamp is in ISO 8601 format, try to parse it + DateTime.parse(timestamp).to_time.to_i + rescue + if timestamp.to_s.length > 10 + # If the timestamp is in milliseconds, convert to seconds + timestamp.to_i / 1000 + else + # If the timestamp is in seconds, return it without change + timestamp.to_i + end + end + end end