Skip to content

Commit

Permalink
Handle negative and zero durations
Browse files Browse the repository at this point in the history
  • Loading branch information
ukstv committed Sep 17, 2014
1 parent 746104a commit 8bfb134
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 12 deletions.
33 changes: 21 additions & 12 deletions lib/duration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,22 @@ def %(other)
# Formats a duration in ISO8601.
# @see http://en.wikipedia.org/wiki/ISO_8601#Durations
def iso8601
output = 'P'

number_of_days = weeks * 7 + days
output << "#{number_of_days}D" if number_of_days > 0
if seconds > 0 || minutes > 0 || hours > 0
output << 'T'
output << "#{hours}H" if hours > 0
output << "#{minutes}M" if minutes > 0
output << "#{seconds}S" if seconds > 0
end
if present?
output = 'P'

number_of_days = weeks * 7 + days
output << "#{number_of_days}D" if number_of_days > 0
if seconds > 0 || minutes > 0 || hours > 0
output << 'T'
output << "#{hours}H" if hours > 0
output << "#{minutes}M" if minutes > 0
output << "#{seconds}S" if seconds > 0
end

output
negative? ? "-#{output}" : output
else
'PT0S'
end
end

# @return true if total is 0
Expand All @@ -114,6 +118,10 @@ def present?
!blank?
end

def negative?
@negative
end

# Format a duration into a human-readable string.
#
# %w => weeks
Expand Down Expand Up @@ -210,7 +218,8 @@ def format(format_str)
def calculate!
multiples = [MULTIPLES[:weeks], MULTIPLES[:days], MULTIPLES[:hours], MULTIPLES[:minutes], MULTIPLES[:seconds]]
units = []
@total = @seconds.to_f.round
@negative = @seconds < 0
@total = @seconds.abs.to_f.round
multiples.inject(@total) do |total, multiple|
# Divide into largest unit
units << total / multiple
Expand Down
12 changes: 12 additions & 0 deletions test/test_duration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,18 @@
assert_equal "PT1H30S", d.iso8601
end

it 'should format empty duration' do
d = Duration.new(0)
assert_equal 'PT0S', d.iso8601
end

it 'should format negative duration' do
d = Duration.new(-1)
assert_equal '-PT1S', d.iso8601

d = Duration.new(-100)
assert_equal '-PT1M40S', d.iso8601
end
end

describe "utilities methods" do
Expand Down

0 comments on commit 8bfb134

Please sign in to comment.