lib/periodic/duration.rb in farski-periodic-1.2.0 vs lib/periodic/duration.rb in farski-periodic-1.2.1

- old
+ new

@@ -1,8 +1,8 @@ require 'bigdecimal' -module Periodic +module Periodic module Duration module Units TIME = Hash.new TIME[:seconds] = { :factor => 1, :directive => /%s/ } TIME[:minutes] = { :factor => 60, :directive => /%m/ } @@ -21,13 +21,16 @@ string.gsub!(/!(\d):/, '!0\1:') string.gsub!(/^(\d):/, '0\1:') string.gsub!(/:(\d):/, ':0\1:') string.gsub!(/:(\d):/, ':0\1:') # needs to happen twice?? string.gsub!(/:(\d(.\d)*)$/, ':0\1') + + # remove leading zero-value digitals + string.sub!(/[0:]*/, '') else # if the string starts with a number we can assume the value-label pairs are like '10 minutes' - if string[0,1].match(/\d/) + if string[0,1].match(/\d/) || string[0,1] == "!" string = string.split(/(!?\d[.\d]*[-_:, a-zA-Z]+)/).delete_if{|x| x == ""}.inject(String.new) { |memo, s| memo << ((s.match(/!/) || s.match(/[1-9]/)) ? s : "") } # if starts with a letter we can assume the value-label pairs are like 'minutes: 10' else string = string.split(/([-A-Za-z: ,]+\d[.\d]*)/).delete_if{|x| x == ""}.inject(String.new) { |memo, s| memo << ((s.match(/!/) || s.match(/[1-9]/)) ? s : "") } @@ -35,16 +38,16 @@ end # remove leading zero-value digitals string.sub!(/[0:]*/, '') end - string.gsub(/!/, '') + string.strip.gsub(/!/, '') end class Duration def initialize(seconds) - @seconds = seconds + @seconds = (seconds.is_a?(Float) ? seconds.to_f : seconds) end def format(format = '%y:%d:%h:%m:%s', precision = nil) string, nondirective_units, values, smallest_unit_directive = format, [], Hash.new, nil @@ -60,11 +63,11 @@ # correct for any left over time that's is fractional for all the included units values[smallest_unit_directive] += nondirective_units.inject(0) { |total, u| total += (send(u).to_f * Periodic::Duration::Units::TIME[u][:factor] / Periodic::Duration::Units::TIME[smallest_unit_directive][:factor]) } if (!Periodic::Duration::Units::TIME_ORDER.reverse[i+1] && !nondirective_units.empty?) end values[smallest_unit_directive] = case precision - when nil then (values[smallest_unit_directive] % 1 == 0) ? values[smallest_unit_directive].to_i : values[smallest_unit_directive] + when nil then (values[smallest_unit_directive] % 1 == 0) && !@seconds.is_a?(Float) ? values[smallest_unit_directive].to_i : values[smallest_unit_directive] when 0 then values[smallest_unit_directive].to_i else (values[smallest_unit_directive] * (10 ** precision)).round / (10 ** precision).to_f end return Periodic::Duration.sanitize_formatted_string(values.inject(string) { |str, data| str.sub!(Periodic::Duration::Units::TIME[data[0]][:directive], data[1].to_s) }) @@ -75,6 +78,8 @@ define_method("whole_" + unit.to_s) { (@seconds.to_f / Periodic::Duration::Units::TIME[unit][:factor]).floor } define_method(unit) { ((Periodic::Duration::Units::TIME_ORDER[i+1] ? BigDecimal.new(@seconds.to_f.to_s) % BigDecimal.new(Periodic::Duration::Units::TIME[Periodic::Duration::Units::TIME_ORDER[i+1]][:factor].to_f.to_s) : @seconds.to_f) / Periodic::Duration::Units::TIME[unit][:factor].to_f).send(unit == :seconds ? :to_f : :floor) } end end end -end +end + +puts Periodic::Duration::Duration.new(60).format('!%y years %d days %h hours %m minutes %s seconds') \ No newline at end of file