Ruby/Rails - How to convert seconds to time?

后端 未结 4 1723
既然无缘
既然无缘 2021-02-19 16:52

I need to perform the following conversion:

0     -> 12.00AM
1800  -> 12.30AM
3600  -> 01.00AM
...
82800 -> 11.00PM
84600 -> 11.30PM
相关标签:
4条回答
  • 2021-02-19 17:30

    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

    0 讨论(0)
  • 2021-02-19 17:35

    In other solutions, the hour-counter would be reset to 00 when crossing 24-hour day boundaries. Also beware that Time.at rounds down, so it will give the wrong result if the input has any fractional seconds (f.ex. when t=479.9 then Time.at(t).utc.strftime("%H:%M:%S") will give 00:07:59 and not 00:08:00` which is the correct one).

    If you want a way to convert any number of seconds (even high counts larger than 24-hour day spans) into an ever increasing HH:MM:SS counter, and handle potential fractional seconds, then try this:

    # Will take as input a time in seconds (which is typically a result after subtracting two Time objects),
    # and return the result in HH:MM:SS, even if it exceeds a 24 hour period.
    def formatted_duration(total_seconds)
      total_seconds = total_seconds.round # to avoid fractional seconds potentially compounding and messing up seconds, minutes and hours
      hours = total_seconds / (60*60)
      minutes = (total_seconds / 60) % 60 # the modulo operator (%) gives the remainder when leftside is divided by rightside. Ex: 121 % 60 = 1
      seconds = total_seconds % 60
      [hours, minutes, seconds].map do |t|
        # Right justify and pad with 0 until length is 2. 
        # So if the duration of any of the time components is 0, then it will display as 00
        t.round.to_s.rjust(2,'0')
      end.join(':')
    end
    

    Modified from @springerigor's and suggestion in the discussion at https://gist.github.com/shunchu/3175001

    0 讨论(0)
  • 2021-02-19 17:38

    The simplest one-liner simply ignores the date:

    Time.at(82800).utc.strftime("%I:%M%p")
    
    #-> "11:00PM"
    
    0 讨论(0)
  • 2021-02-19 17:44

    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

    0 讨论(0)
提交回复
热议问题