Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert 24 integer to 12 hour with am/pm

I'm using ruby.

I'm trying to figure out how to convert the following..

14 becomes 2 pm

0 becomes 12 am

23 becomes 11 pm

Thanks!

like image 999
Tallboy Avatar asked Mar 10 '13 22:03

Tallboy


People also ask

How do you convert 24 hour to AM PM?

Converting from 24 hour to 12 hour clockStarting from the first hour of the day (0:00 / midnight to 0:59), add 12 hours and AM to the time: 0:30 = 12:30 AM.

How do I convert 24 hour clock to 12 hour clock in Python?

The key to this code is to use the library function time. strptime() to parse the 24-hour string representations into a time. struct_time object, then use library function time. strftime() to format this struct_time into a string of your desired 12-hour format.


2 Answers

[14, 0, 23].map { |hour| Time.parse("#{hour}:00").strftime("%l %P") }
=> [" 2 pm", "12 am", "11 pm"]
like image 108
Mori Avatar answered Sep 28 '22 05:09

Mori


I like @Mori's answer because it lets Time do the heavy lifting, but using Benchmark we can see which is the most CPU intensive:

This is what I'd have written:

def am_pm(hour)
  meridian = (hour >= 12) ? 'pm' : 'am'
  hour = case hour
        when 0, 12
          12
        when 13 .. 23
          hour - 12
        else
          hour
        end

  "#{ hour } #{ meridian }"
end

Benchmark:

require 'benchmark'
require 'time'

def mori(hour)
  Time.parse("#{hour}:00").strftime("%l %P")
end

def convert h
  p, l = h.divmod(12)
  "#{l.zero? ? 12 : l} #{p.zero? ? "a" : "p"}m"
end

def am_pm(hour)
  meridian = (hour >= 12) ? 'pm' : 'am'
  hour = case hour
        when 0, 12
          12
        when 13 .. 23
          hour - 12
        else
          hour
        end

  "#{ hour } #{ meridian }"
end

def hour_24_to_12(hour_24)
  hour_12 = hour_24 - 12

  if hour_12 == 0
    return "12 pm"
  elsif hour_12 == -12
    return "12 am"
  elsif hour_12 > 0
    return "#{hour_12} pm"
  elsif hour_12 < 0
    return "#{hour_24} am"
  else
    # The passed-in time is outside the range o 0-23,
    # so you may need to deal with this however you
    # feel is appropriate
  end
end

HRS = [0, 14, 23]
N = 100_000

puts RUBY_VERSION

HRS.each { |hr| puts "am_pm:         #{ am_pm(hr)         }" }
HRS.each { |hr| puts "convert:       #{ convert(hr)       }" }
HRS.each { |hr| puts "hour_24_to_12: #{ hour_24_to_12(hr) }" }
HRS.each { |hr| puts "mori:          #{ mori(hr)          }" }

Benchmark.bm(13) do |b|
  b.report('am_pm')         { N.times { HRS.each { |h| am_pm(h)         } } }
  b.report('convert')       { N.times { HRS.each { |h| convert(h)       } } }
  b.report('hour_24_to_12') { N.times { HRS.each { |h| hour_24_to_12(h) } } }
  b.report('mori')          { N.times { HRS.each { |h| mori(h)          } } }
end

Which outputs:

1.9.3
am_pm:         12 am
am_pm:         2 pm
am_pm:         11 pm
convert:       12 am
convert:       2 pm
convert:       11 pm
hour_24_to_12: 12 am
hour_24_to_12: 2 pm
hour_24_to_12: 11 pm
mori:          12 am
mori:           2 pm
mori:          11 pm
                    user     system      total        real
am_pm           1.230000   0.000000   1.230000 (  1.228159)
convert         1.280000   0.000000   1.280000 (  1.286672)
hour_24_to_12   0.640000   0.000000   0.640000 (  0.642993)
mori           20.940000   0.020000  20.960000 ( 21.003620)

And the same tests only running under Ruby 2.0-p0:

2.0.0
am_pm:         12 am
am_pm:         2 pm
am_pm:         11 pm
convert:       12 am
convert:       2 pm
convert:       11 pm
hour_24_to_12: 12 am
hour_24_to_12: 2 pm
hour_24_to_12: 11 pm
mori:          12 am
mori:           2 pm
mori:          11 pm
                    user     system      total        real
am_pm           0.440000   0.000000   0.440000 (  0.433303)
convert         0.410000   0.000000   0.410000 (  0.412183)
hour_24_to_12   0.200000   0.000000   0.200000 (  0.201894)
mori            9.910000   0.010000   9.920000 (  9.921940)
like image 38
the Tin Man Avatar answered Sep 28 '22 06:09

the Tin Man