Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Convert seconds into HH:MM:SS in Ruby
t = 236 # seconds
Time.at(t).utc.strftime("%H:%M:%S")
=> "00:03:56"
# Reference
# http://stackoverflow.com/questions/3963930/ruby-rails-how-to-convert-seconds-to-time
@fguillen

This comment has been minimized.

Copy link

commented Mar 6, 2014

I like it! :)

@DaveCollinsJr

This comment has been minimized.

Copy link

commented Mar 13, 2014

+1

@Saidbek

This comment has been minimized.

Copy link

commented Mar 15, 2014

+1

@rajdeep26

This comment has been minimized.

Copy link

commented Apr 9, 2014

Thanks. Helped a lot! :)

@peijiehu

This comment has been minimized.

Copy link

commented Jul 23, 2014

Like! Thanks!

@evanmcc92

This comment has been minimized.

Copy link

commented Aug 19, 2014

perfect thanks!

@amerem

This comment has been minimized.

Copy link

commented Dec 12, 2014

Awesome! Thank you!

@NayanaBhagat

This comment has been minimized.

Copy link

commented Dec 15, 2014

What if we want to display more than 24hours?, the above solution neglects 24 hours and prints the remaining time since its TIME function
Can any one help?

@NayanaBhagat

This comment has been minimized.

Copy link

commented Dec 15, 2014

Got this solution in one of the blogs

[total_time / 3600, total_time/ 60 % 60, total_time % 60].map { |t| t.to_s.rjust(2,'0') }.join(':')

Here total_time is total number of seconds

Works for me 😄

@andre1810

This comment has been minimized.

Copy link

commented Dec 16, 2014

+1

@tjchambers

This comment has been minimized.

Copy link

commented Mar 11, 2015

+1

@laalex

This comment has been minimized.

Copy link

commented Mar 18, 2015

+1

@yogendra689

This comment has been minimized.

Copy link

commented Apr 22, 2015

+1 thanks

@zackexplosion

This comment has been minimized.

Copy link

commented May 22, 2015

+1

@springerigor

This comment has been minimized.

Copy link

commented Jun 2, 2015

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.

@nmenag

This comment has been minimized.

Copy link

commented Jun 30, 2015

Nice!

@shoaib-iqbal

This comment has been minimized.

Copy link

commented Aug 8, 2015

+1 thanks

@lalitlogical

This comment has been minimized.

Copy link

commented Aug 28, 2015

+1 Nice!

@boomshadow

This comment has been minimized.

Copy link

commented Sep 29, 2015

@springerigor Super +1! Thanks!

@KarthikRamu1

This comment has been minimized.

Copy link

commented Oct 27, 2015

Thanks!

@TecnoSigma

This comment has been minimized.

Copy link

commented Oct 30, 2015

Thanks!

@Banta

This comment has been minimized.

Copy link

commented Nov 25, 2015

+1

@cheenwe

This comment has been minimized.

Copy link

commented Dec 16, 2015

+1

@dmcwilliams

This comment has been minimized.

Copy link

commented Dec 18, 2015

+1

@peter-trerotola

This comment has been minimized.

Copy link

commented Jan 3, 2016

❤️

@petehamilton

This comment has been minimized.

Copy link

commented Feb 10, 2016

❤️ perfect.

@lonny

This comment has been minimized.

Copy link

commented Feb 24, 2016

Kudos to NayanaBhagat.
I have expanded on her idea just a bit to add optional decimal seconds, which adds to the complexity quite a bit.
I have limited the decimals to 8 due to floating point error.

(Update: I fixed a bug that wasn't displaying fractional seconds correctly.)

def hms(seconds, decimals = 0)
  int   = seconds.floor
  decs  = [decimals, 8].min
  frac  = seconds - int
  hms   = [int / 3600, (int / 60) % 60, int % 60].map { |t| t.to_s.rjust(2,'0') }.join(':')
  if decs > 0
    fp = (frac == 0) ? '.00' : "#{(frac).round(decs)}"[1..-1]
    hms  << fp
  end
  hms
end
@elquimista

This comment has been minimized.

Copy link

commented Mar 3, 2016

Like it 👍

@StephaneJuban

This comment has been minimized.

Copy link

commented Apr 9, 2016

+1

@sakares

This comment has been minimized.

Copy link

commented Apr 14, 2016

+1

@renandanton

This comment has been minimized.

Copy link

commented Jul 3, 2016

How do i convert a string '1m30s' in seconds time ?

@Madh93

This comment has been minimized.

Copy link

commented Aug 1, 2016

Like a charm 👍

@whrishi

This comment has been minimized.

Copy link

commented Aug 2, 2016

Gr8. Thanks NayanaBhagat for providing one line solution for greater than 24 hours

@tomascharad

This comment has been minimized.

Copy link

commented Aug 23, 2016

Amazing. I had a float in hours (i.e.: 6.5), so I just did

Time.at(t.to_hours).utc.strftime("%H:%M:%S")
@sweeninalla

This comment has been minimized.

Copy link

commented Sep 21, 2016

how to convert 1:30 format to 1 hr 30 mins.|Please advise

@Qasem-h

This comment has been minimized.

Copy link

commented Oct 1, 2016

+1

@Andoresu250

This comment has been minimized.

Copy link

commented Dec 12, 2016

+1

@lonny

This comment has been minimized.

Copy link

commented Jan 1, 2017

sweeninalla, just off the top of my head:

before = "1:30"
hrs, mins = before.split(':')
after = "#{hrs} hrs #{mins} mins"
@jackli0855

This comment has been minimized.

Copy link

commented Mar 6, 2017

+1

@lppedrohs

This comment has been minimized.

Copy link

commented Mar 13, 2017

+1

@Evanto

This comment has been minimized.

Copy link

commented Apr 12, 2017

If I have 2 integers 07 hours and 15 minutes, how can I convert them to time and get 07:15 time in Ruby?

@maknahar

This comment has been minimized.

Copy link

commented Jul 19, 2017

+1

@kinnrot

This comment has been minimized.

Copy link

commented Jul 19, 2017

+3

@guillermoap

This comment has been minimized.

Copy link

commented Jul 21, 2017

+1

@Aminbhs

This comment has been minimized.

Copy link

commented Aug 26, 2017

+1

@redbar0n

This comment has been minimized.

Copy link

commented Sep 8, 2017

I have used the solutions of @springerigor and @NayanaBhagat to make it a bit more readable / understandable than a cryptic oneliner. It also removes decimals by using rounding.

# 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)
  hours = total_seconds / (60 * 60)
  minutes = (total_seconds / 60) % 60
  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
@somethvictory

This comment has been minimized.

Copy link

commented Nov 20, 2017

+1

@tangens

This comment has been minimized.

Copy link

commented Jan 17, 2018

+1

@RemiDuvoux

This comment has been minimized.

Copy link

commented Feb 23, 2018

+1

@iGEL

This comment has been minimized.

Copy link

commented Mar 6, 2018

If you want to have output like 1h 30m:

def seconds_to_str(seconds)
  ["#{seconds / 3600}h", "#{seconds / 60 % 60}m", "#{seconds % 60}s"]
    .select { |str| str =~ /[1-9]/ }.join(" ")
end

seconds_to_str(2) # => "2s"
seconds_to_str(69) # => "1m 9s"
seconds_to_str(600) # => "10m"*
seconds_to_str(43_200) #=> "12h"
seconds_to_str(43_205) # => "12h 5s" <- no minutes!
seconds_to_str(100_000) # => "27h 46m 40s" <- you could adjust it for days etc.
@ardinusawan

This comment has been minimized.

Copy link

commented Mar 22, 2018

+1

@joerzepiejewski

This comment has been minimized.

Copy link

commented May 9, 2018

👍

@dblock

This comment has been minimized.

Copy link

commented Jun 26, 2018

Beware of round being used here. If total seconds is 479.8282647584973

  • @redbar0n code produces the wrong result, "00:08:60"
  • @lonny code and the original Time.at version round down, so "00:07:59", but this is not the best approximation

Related and working:

@zalivanvitaly

This comment has been minimized.

Copy link

commented Sep 6, 2018

+1

@eliasdouglas

This comment has been minimized.

Copy link

commented Feb 19, 2019

+1

@dhurba87

This comment has been minimized.

Copy link

commented Feb 21, 2019

+1

@YoshitsuguFujii

This comment has been minimized.

Copy link

commented Mar 15, 2019

+1

@alexwebgr

This comment has been minimized.

Copy link

commented Apr 3, 2019

Added days!
extending on @springerigor solution

    def formatted_duration(total_seconds)
      days = total_seconds / (60 * 60 * 24)
      hours = total_seconds / (60 * 60)
      hours -= 24 if days > 0
      minutes = (total_seconds / 60) % 60
      seconds = total_seconds % 60

      "#{days}d #{hours}h #{minutes}m #{seconds}s"
    end
@PoombavaiS

This comment has been minimized.

Copy link

commented Jun 24, 2019

👍

@MelvynSwingler

This comment has been minimized.

Copy link

commented Jul 15, 2019

This is pretty cool!

@itssomething

This comment has been minimized.

Copy link

commented Aug 7, 2019

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.