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

@fguillen fguillen commented Mar 6, 2014

I like it! :)

@DaveCollinsJr

This comment has been minimized.

Copy link

@DaveCollinsJr DaveCollinsJr commented Mar 13, 2014

+1

@Saidbek

This comment has been minimized.

Copy link

@Saidbek Saidbek commented Mar 15, 2014

+1

@rajdeep26

This comment has been minimized.

Copy link

@rajdeep26 rajdeep26 commented Apr 9, 2014

Thanks. Helped a lot! :)

@peijiehu

This comment has been minimized.

Copy link

@peijiehu peijiehu commented Jul 23, 2014

Like! Thanks!

@evanmcc92

This comment has been minimized.

Copy link

@evanmcc92 evanmcc92 commented Aug 19, 2014

perfect thanks!

@amerem

This comment has been minimized.

Copy link

@amerem amerem commented Dec 12, 2014

Awesome! Thank you!

@NayanaBhagat

This comment has been minimized.

Copy link

@NayanaBhagat NayanaBhagat 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

@NayanaBhagat NayanaBhagat 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

@andre1810 andre1810 commented Dec 16, 2014

+1

@tjchambers

This comment has been minimized.

Copy link

@tjchambers tjchambers commented Mar 11, 2015

+1

@laalex

This comment has been minimized.

Copy link

@laalex laalex commented Mar 18, 2015

+1

@yogendra689

This comment has been minimized.

Copy link

@yogendra689 yogendra689 commented Apr 22, 2015

+1 thanks

@zackexplosion

This comment has been minimized.

Copy link

@zackexplosion zackexplosion commented May 22, 2015

+1

@springerigor

This comment has been minimized.

Copy link

@springerigor springerigor 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

@nmenag nmenag commented Jun 30, 2015

Nice!

@shoaib-iqbal

This comment has been minimized.

Copy link

@shoaib-iqbal shoaib-iqbal commented Aug 8, 2015

+1 thanks

@lalitlogical

This comment has been minimized.

Copy link

@lalitlogical lalitlogical commented Aug 28, 2015

+1 Nice!

@boomshadow

This comment has been minimized.

Copy link

@boomshadow boomshadow commented Sep 29, 2015

@springerigor Super +1! Thanks!

@KarthikRamu1

This comment has been minimized.

Copy link

@KarthikRamu1 KarthikRamu1 commented Oct 27, 2015

Thanks!

@TecnoSigma

This comment has been minimized.

Copy link

@TecnoSigma TecnoSigma commented Oct 30, 2015

Thanks!

@Banta

This comment has been minimized.

Copy link

@Banta Banta commented Nov 25, 2015

+1

@cheenwe

This comment has been minimized.

Copy link

@cheenwe cheenwe commented Dec 16, 2015

+1

@dmcwilliams

This comment has been minimized.

Copy link

@dmcwilliams dmcwilliams commented Dec 18, 2015

+1

@peter-trerotola

This comment has been minimized.

Copy link

@peter-trerotola peter-trerotola commented Jan 3, 2016

❤️

@petehamilton

This comment has been minimized.

Copy link

@petehamilton petehamilton commented Feb 10, 2016

❤️ perfect.

@lonny

This comment has been minimized.

Copy link

@lonny lonny 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

@elquimista elquimista commented Mar 3, 2016

Like it 👍

@StephaneJuban

This comment has been minimized.

Copy link

@StephaneJuban StephaneJuban commented Apr 9, 2016

+1

@sakares

This comment has been minimized.

Copy link

@sakares sakares commented Apr 14, 2016

+1

@renandanton

This comment has been minimized.

Copy link

@renandanton renandanton commented Jul 3, 2016

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

@Madh93

This comment has been minimized.

Copy link

@Madh93 Madh93 commented Aug 1, 2016

Like a charm 👍

@whrishi

This comment has been minimized.

Copy link

@whrishi whrishi 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

@tomascharad tomascharad 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

@sweeninalla sweeninalla 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

@Qasem-h Qasem-h commented Oct 1, 2016

+1

@Andoresu250

This comment has been minimized.

Copy link

@Andoresu250 Andoresu250 commented Dec 12, 2016

+1

@lonny

This comment has been minimized.

Copy link

@lonny lonny 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

@jackli0855 jackli0855 commented Mar 6, 2017

+1

@lppedrohs

This comment has been minimized.

Copy link

@lppedrohs lppedrohs commented Mar 13, 2017

+1

@Evanto

This comment has been minimized.

Copy link

@Evanto Evanto 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

@maknahar maknahar commented Jul 19, 2017

+1

@kinnrot

This comment has been minimized.

Copy link

@kinnrot kinnrot commented Jul 19, 2017

+3

@guillermoap

This comment has been minimized.

Copy link

@guillermoap guillermoap commented Jul 21, 2017

+1

@Aminbhs

This comment has been minimized.

Copy link

@Aminbhs Aminbhs commented Aug 26, 2017

+1

@redbar0n

This comment has been minimized.

Copy link

@redbar0n redbar0n 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

@somethvictory somethvictory commented Nov 20, 2017

+1

@tangens

This comment has been minimized.

Copy link

@tangens tangens commented Jan 17, 2018

+1

@RemiDuvoux

This comment has been minimized.

Copy link

@RemiDuvoux RemiDuvoux commented Feb 23, 2018

+1

@iGEL

This comment has been minimized.

Copy link

@iGEL iGEL 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

@ardinusawan ardinusawan commented Mar 22, 2018

+1

@joerzepiejewski

This comment has been minimized.

Copy link

@joerzepiejewski joerzepiejewski commented May 9, 2018

👍

@dblock

This comment has been minimized.

Copy link

@dblock dblock 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

@zalivanvitaly zalivanvitaly commented Sep 6, 2018

+1

@eliasdouglas

This comment has been minimized.

Copy link

@eliasdouglas eliasdouglas commented Feb 19, 2019

+1

@dhurba87

This comment has been minimized.

Copy link

@dhurba87 dhurba87 commented Feb 21, 2019

+1

@YoshitsuguFujii

This comment has been minimized.

Copy link

@YoshitsuguFujii YoshitsuguFujii commented Mar 15, 2019

+1

@alexwebgr

This comment has been minimized.

Copy link

@alexwebgr alexwebgr 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

@PoombavaiS PoombavaiS commented Jun 24, 2019

👍

@MelvynSwingler

This comment has been minimized.

Copy link

@MelvynSwingler MelvynSwingler commented Jul 15, 2019

This is pretty cool!

@itssomething

This comment has been minimized.

Copy link

@itssomething itssomething commented Aug 7, 2019

👍

@pmichaeljones

This comment has been minimized.

Copy link

@pmichaeljones pmichaeljones commented Nov 26, 2019

Solid!

@hdchinh

This comment has been minimized.

Copy link

@hdchinh hdchinh commented Mar 31, 2020

Thanks, really good 😄

@trangtungn

This comment has been minimized.

Copy link

@trangtungn trangtungn commented Apr 7, 2020

+1

@tthuydang

This comment has been minimized.

Copy link

@tthuydang tthuydang commented Sep 12, 2020

+1

@vilusa

This comment has been minimized.

Copy link

@vilusa vilusa commented Oct 16, 2020

+1

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.