I need to perform the following conversion:
0 -> 12.00AM
1800 -> 12.30AM
3600 -> 01.00AM
...
82800 -> 11.00PM
84600 -> 11.30PM
I came up with this:
(0..84600).step(1800){|n| puts "#{n.to_s} #{Time.at(n).strftime("%I:%M%p")}"}
which gives me the wrong time, because Time.at(n) expects n to be number of seconds from epoch:
0 -> 07:00PM
1800 -> 07:30PM
3600 -> 08:00PM
...
82800 -> 06:00PM
84600 -> 06:30PM
What would be the most optimal, time zone independent solution for this transformation?
The simplest one-liner simply ignores the date:
Time.at(82800).utc.strftime("%I:%M%p")
#-> "11:00PM"
Not sure if this is better than
(Time.local(1,1,1) + 82800).strftime("%I:%M%p")
def hour_minutes(seconds)
Time.at(seconds).utc.strftime("%I:%M%p")
end
irb(main):022:0> [0, 1800, 3600, 82800, 84600].each { |s| puts "#{s} -> #{hour_minutes(s)}"}
0 -> 12:00AM
1800 -> 12:30AM
3600 -> 01:00AM
82800 -> 11:00PM
84600 -> 11:30PM
Stephan
Two offers:
The elaborate DIY solution:
def toClock(secs)
h = secs / 3600; # hours
m = secs % 3600 / 60; # minutes
if h < 12 # before noon
ampm = "AM"
if h = 0
h = 12
end
else # (after) noon
ampm = "PM"
if h > 12
h -= 12
end
end
ampm = h <= 12 ? "AM" : "PM";
return "#{h}:#{m}#{ampm}"
end
the Time solution:
def toClock(secs)
t = Time.gm(2000,1,1) + secs # date doesn't matter but has to be valid
return "#{t.strftime("%I:%M%p")} # copy of your desired format
end
HTH