Reputation: 126329
How can we convert a wait-time in seconds into a string that naturally expresses the wait-time to a human?
Example Input & Output
Upvotes: 1
Views: 223
Reputation: 110675
Code
require 'time'
FMT = [[s = 60, "%-S seconds", :NO_ROUND],
[s *= 60, "%-M minutes", :ROUND_MINS],
[s *= 24, "until %-l:%M %p today", :ROUND_UP_MINS_15],
[s * 7, "until %A %-l:%M %p", :ROUND_UP_MINS_15],
[Float::INFINITY, "until %-_m/%d/%y at %-l:%M %p", :ROUND_UP_MINS_15]]
def fmt_duration(start_time = Date.today.to_time, elapsed_seconds)
secs = start_time.to_i + elapsed_seconds
_, fmt, round = FMT.find { |max_secs_plus_1, *_| elapsed_seconds < max_secs_plus_1 }
rnd_secs =
case round
when :NO_ROUND
secs
when :ROUND_MINS
mins = (secs/60.0).round
mins -= 1 if mins % 60 == 0
60 * mins
when :ROUND_UP_MINS_15
900 * (secs/900.0).ceil
end
Time.at(rnd_secs).strftime(fmt)
end
Note that
puts "#{FMT}"
#=> [[60, "%-S seconds", :NO_ROUND],
# [3600, "%-M minutes", :ROUND_MINS],
# [86400, "until %-l:%M %p today", :ROUND_UP_MINS_15],
# [604800, "until %A %-l:%M %p", :ROUND_UP_MINS_15],
# [Infinity, "until %-_m/%d/%y at %-l:%M %p", :ROUND_UP_MINS_15]]
See Time#strftime for a listing of Date
and Time
formatting codes in the second column of FMT
.
Examples
def time_to_secs(days, hours, minutes, seconds)
seconds + 60 * (minutes + 60 * (hours + 24 * days))
end
secs = time_to_secs( 0, 0, 0, 37) #=> 37
fmt_duration(secs) #=> "37 seconds"
secs = time_to_secs( 0, 0, 41, 37) #=> 2_497
fmt_duration(secs) #=> "42 minutes"
secs = time_to_secs( 0, 13, 41, 37) #=> 49_297
fmt_duration(secs) #=> "until 1:45 PM today"
secs = time_to_secs( 6, 23, 36, 37) #=> 603_397
fmt_duration(secs) #=> "until Tuesday 11:45 PM"
secs = time_to_secs(24, 13, 41, 37) #=> 2_122_897
fmt_duration(secs) #=> "until 7/22/17 at 1:45 PM"
Upvotes: 1