From ae9b9f1ab79e4bb3e3ca8a23412ce1384dc0ee0e Mon Sep 17 00:00:00 2001 From: Guillaume Virlet Date: Sat, 18 Sep 2021 10:15:50 +0200 Subject: [PATCH] add ability to set time offset with loading file + enhance spec for Local time --- README.md | 20 ++++++++++++++++++++ lib/fit.rb | 3 ++- lib/fit/file/types.rb | 13 ++++++++++++- spec/fit/file/types_spec.rb | 9 +++++++-- 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f60a5b9..b75cd0b 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,26 @@ fit_file = Fit.load_file(ARGV[0]) records = fit_file.records.select{ |r| r.content.record_type != :definition }.map{ |r| r.content } ``` +If some times returned for your file are around 1989 or 1990, then you need to get the offset and pass it to the `load_file` method +This requires loading the file 2 times (1 to get the offset, and 1 to read the file with the offseted date) +```ruby +require 'fit' + +fit_file = Fit.load_file(ARGV[0]) + +offset = nil +records = fit_file.records.select { |r| r.content.record_type == :activity }.map(&:content) +rec = records[0] +local_ts = rec.send(:raw_timestamp).to_i +offset = rec.send(:raw_local_timestamp).to_i if local_ts < 268435456 + + +fit_file = Fit.load_file(ARGV[0], offset) + +records = fit_file.records.select{ |r| r.content.record_type != :definition }.map{ |r| r.content } + +``` + ## Supported files This library has been tested with files coming from the following devices: diff --git a/lib/fit.rb b/lib/fit.rb index 3a452ee..0ef22c2 100644 --- a/lib/fit.rb +++ b/lib/fit.rb @@ -17,7 +17,8 @@ require 'fit/version' module Fit - def self.load_file(path) + def self.load_file(path, time_offset = nil) + Fit::File::Types.time_offset = time_offset File.read ::File.open(path) end end diff --git a/lib/fit/file/types.rb b/lib/fit/file/types.rb index 4efc3d3..384fafa 100644 --- a/lib/fit/file/types.rb +++ b/lib/fit/file/types.rb @@ -4,6 +4,7 @@ module Fit class File module Types @@types = {} + @@time_offset = nil class << self def add_type(name, type, option = {}) @@ -16,10 +17,20 @@ def get_type_definition(name) nil end + def time_offset=(time_offset) + @@time_offset = time_offset + end + def date_time_value(time, values, parameters) val = values.invert if time < val['min'] - time.to_s + if @@time_offset + offsetted_time = @@time_offset + time + res = parameters[:utc] ? Time.utc(1989, 12, 31) + offsetted_time : Time.local(1989, 12, 31) + offsetted_time + res.to_s + else + time.to_s + end else res = parameters[:utc] ? Time.utc(1989, 12, 31) + time : Time.local(1989, 12, 31) + time res.to_s diff --git a/spec/fit/file/types_spec.rb b/spec/fit/file/types_spec.rb index 2b580e6..1e93af8 100644 --- a/spec/fit/file/types_spec.rb +++ b/spec/fit/file/types_spec.rb @@ -37,6 +37,12 @@ expect(described_class.date_time_value(9999, { 268435456 => 'min' }, { utc: true })).to eql '9999' expect(described_class.date_time_value(9999, { 268435456 => 'min' }, { utc: false })).to eql '9999' end + + it 'returns offsetted system time when offset is defined' do + described_class.time_offset = 788392680 + expect(described_class.date_time_value(738748, { 268435456 => 'min' }, + { utc: true })).to eql '2015-01-02 11:10:28 UTC' + end end context 'when value is above min' do @@ -49,9 +55,8 @@ context 'with local mode' do it 'returns exact date in locale time zone' do - # TODO: manage answer based on current system local expect(described_class.date_time_value(790509304, { 268435456 => 'min' }, - { utc: false })).not_to match(/UTC$/) + { utc: false })).to match(/^2015-01-18 09:55:04 [+-]\d{4}$/) end end end