Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions lib/api/v3/utilities/date_time_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,11 @@ def format_datetime(datetime, allow_nil: false)
def format_duration_from_hours(hours, allow_nil: false)
return nil if hours.nil? && allow_nil

Duration.new(seconds: hours * 3600).iso8601
# Duration.new truncates its :seconds argument via Float#to_i
# (ruby-duration gem) rather than rounding -- round explicitly
# here first so e.g. 3600.9 seconds (1h 0.9s) serializes as
# PT1H1S, not silently dropped to PT1H.
Duration.new(seconds: (hours * 3600).round).iso8601
end

def parse_duration_to_hours(duration, property_name, allow_nil: false)
Expand All @@ -104,7 +108,11 @@ def parse_duration_to_hours(duration, property_name, allow_nil: false)
def format_duration_from_days(days, allow_nil: false)
return nil if days.nil? && allow_nil

Duration.new(seconds: days * 3600 * 24).iso8601
# Duration.new truncates its :seconds argument via Float#to_i
# (ruby-duration gem) rather than rounding -- round explicitly
# here first, same as format_duration_from_hours above, so a
# fractional-day value doesn't silently lose up to ~1s of precision.
Duration.new(seconds: (days * 3600 * 24).round).iso8601
end

def parse_duration_to_days(duration, property_name, allow_nil: false)
Expand Down
12 changes: 10 additions & 2 deletions spec/lib/api/v3/utilities/date_time_formatter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,10 @@
expect(subject.format_duration_from_hours(5.5)).to eq("PT5H30M")
end

it "includes seconds" do
expect(subject.format_duration_from_hours(5.501)).to eq("PT5H30M3S")
it "includes seconds, rounded rather than truncated" do
# 5.501h == 19803.6s -- rounds up to 19804s (PT5H30M4S), not
# truncated down to 19803s (PT5H30M3S).
expect(subject.format_duration_from_hours(5.501)).to eq("PT5H30M4S")
end

it "formats ints" do
Expand Down Expand Up @@ -230,6 +232,12 @@
expect(subject.format_duration_from_days(5.501)).to eq("P5DT12H1M26S")
end

it "rounds rather than truncates seconds" do
# 5.5006 days == 475251.84s -- rounds up to 475252s (P5DT12H52S), not
# truncated down to 475251s (P5DT12H51S).
expect(subject.format_duration_from_days(5.5006)).to eq("P5DT12H52S")
end

it "formats ints" do
expect(subject.format_duration_from_days(5)).to eq("P5D")
end
Expand Down
Loading