require 'alib' this = open __FILE__ n_threads = 5 alib.util.threadify this, n_threads do |line, lineno| puts line end __END__ class Time class Distance < ::Hash def method_missing m, *a, &b super unless has_key? m.to_sym self[m.to_sym] end end def distance other, limit = :years s = ( to_i - other.to_i ).abs d = Distance.new format = Array.new values = Array.new ops = [ [ :years, 31536000 ], [ :months, 2592000 ], [ :weeks, 604800 ], [ :days, 86400 ], [ :hours, 3600 ], [ :minutes, 60 ], [ :seconds, 1 ], ] index = 0 ops.each_with_index do |pair, i| unit = pair.first break(index = i) if limit == unit end ops[index .. -1].each do |pair| unit, n = pair if n > s value = 0 d[unit] = value else value, s = s.divmod n d[unit] = value values << value unit = value == 1 ? unit.to_s.chop : unit.to_s format << "%d #{ unit }" end end if format.size > 1 comma = ',' if format.size > 2 format[-2] = "#{ format[-2] }#{ comma } and #{ format[-1] }" format.pop end format = format.join ', ' d[:formatted] = format % values d end end a = Time.now b = a + 120 + 2 p a.distance(b, :days).formatted a = Time.now b = a + (2 * 3600) p a.distance(b).formatted a = Time.now b = a + (31536000) p a.distance(b).formatted a = Time.now b = a + (31536000 + 3600 + 60 + 42) p a.distance(b).formatted a = Time.now b = a + (31536000 + 3600 + 60 + 42) p a.distance(b, :weeks).formatted