Convert duration to hours:minutes:seconds (or similar) in Rails 3 or Ruby

后端 未结 13 754
一整个雨季
一整个雨季 2021-01-29 23:52

I have a feeling there is a simple/built-in way to do this but I can\'t find it.

I have a duration (in seconds) in an integer and I want to display it in a friendly form

相关标签:
13条回答
  • 2021-01-30 00:25

    I use this to show time durations in my Rails Project:

    1. Add a custom method to the Integer class. You can create a new file called pretty_duration.rb in the initializers folder:

      class Integer
          def pretty_duration
              parse_string = 
                  if self < 3600
                      '%M:%S'
                  else
                      '%H:%M:%S'
                  end
      
              Time.at(self).utc.strftime(parse_string)
          end
      end
      
    2. Call seconds.pretty_duration anywhere in your project:

      275.pretty_duration     # => "04:35"
      9823.pretty_duration    # => "02:43:43"
      

    This answer builds up on Lev Lukomsky's Code

    0 讨论(0)
  • 2021-01-30 00:25

    Using Time.utc.strftime works only for values when total number of hours is less then 24:

    2.2.2 :004 > Time.at(60 * 60).utc.strftime('%H h %M m')
    => "01 h 00 m"
    

    For greater values it returns incorrect results:

    2.2.2 :006 > Time.at(60 * 60 * 24).utc.strftime('%H h %M m')
     => "00 h 00 m"
    

    I suggest using the simplest method I found for this problem:

      def formatted_duration total_seconds
        hours = total_seconds / (60 * 60)
        minutes = (total_seconds / 60) % 60
        seconds = total_seconds % 60
        "#{ hours } h #{ minutes } m #{ seconds } s"
      end
    

    You can always adjust returned value to your needs.

    0 讨论(0)
  • 2021-01-30 00:27

    An answer inspired from Lev Lukomsky's one taking advantage of ActiveSupport::Duration, and handling milliseconds (useful to benchmark code)

    # duration in ms modulus number of ms in one second
    milliseconds = duration.in_milliseconds % 1.second.in_milliseconds
    
    # duration in seconds modulus number of seconds in one minute
    seconds = (duration / 1.second) % (1.minute / 1.second)
    
    # duration in minutes modulus number of minutes in one hour
    minutes = (duration / 1.minute) % (1.hour / 1.minute)
    
    # duration in hours modulus number of hours in one day
    hours = (duration / 1.hour) % (1.day / 1.hour)
    
    format("%02d:%02d:%02d:%03d", hours, minutes, seconds, milliseconds) #=> "12:05:00:001"
    

    Of course you can extend this easily with days, months, years, etc using related ActiveSupport methods and repeating the same structure.

    Keep in mind that for too long durations, this may be inaccurate since the duration of 1 month is not fixed in number of days, and I'm not sure how AS:Duration deals with that.

    0 讨论(0)
  • 2021-01-30 00:28

    Just to throw in my 2 cents:

    Time.at(i).utc.strftime((i < 3600) ? '%-M minutes and %-S seconds' : '%-H hours, %-M minutes, and %-S seconds')
    

    Built off of Xiao Bin's answer.

    0 讨论(0)
  • 2021-01-30 00:30

    Be careful with the duration longer than one day.

    (timing/3600).to_i.to_s.rjust(2,'0') + ":"+Time.at(timing).utc.strftime("%M:%S")
    
    0 讨论(0)
  • 2021-01-30 00:35

    Summing up:

    assuming that total_seconds = 3600

    Option 1:

    distance_of_time_in_words(total_seconds) #=> "about 1 hour"
    

    Option 2:

    Time.at(total_seconds).utc.strftime("%H:%M:%S") #=> "01:00:00"
    

    Option 3:

    seconds = total_seconds % 60
    minutes = (total_seconds / 60) % 60
    hours = total_seconds / (60 * 60)
    
    format("%02d:%02d:%02d", hours, minutes, seconds) #=> "01:00:00"
    

    use Option1 if you want words, Option2 if you want H:M:S format, Option3 if you want H:M:S format and there can be more than 24 hours

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