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 commented Mar 6, 2014

I like it! :)

@DaveCollinsJr

This comment has been minimized.

Copy link

DaveCollinsJr commented Mar 13, 2014

+1

@Saidbek

This comment has been minimized.

Copy link

Saidbek commented Mar 15, 2014

+1

@rajdeep26

This comment has been minimized.

Copy link

rajdeep26 commented Apr 9, 2014

Thanks. Helped a lot! :)

@peijiehu

This comment has been minimized.

Copy link

peijiehu commented Jul 23, 2014

Like! Thanks!

@evanmcc92

This comment has been minimized.

Copy link

evanmcc92 commented Aug 19, 2014

perfect thanks!

@amerem

This comment has been minimized.

Copy link

amerem commented Dec 12, 2014

Awesome! Thank you!

@NayanaBhagat

This comment has been minimized.

Copy link

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 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 commented Dec 16, 2014

+1

@tjchambers

This comment has been minimized.

Copy link

tjchambers commented Mar 11, 2015

+1

@laalex

This comment has been minimized.

Copy link

laalex commented Mar 18, 2015

+1

@yogendra689

This comment has been minimized.

Copy link

yogendra689 commented Apr 22, 2015

+1 thanks

@zackexplosion

This comment has been minimized.

Copy link

zackexplosion commented May 22, 2015

+1

@springerigor

This comment has been minimized.

Copy link

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 commented Jun 30, 2015

Nice!

@shoaib-iqbal

This comment has been minimized.

Copy link

shoaib-iqbal commented Aug 8, 2015

+1 thanks

@lalitlogical

This comment has been minimized.

Copy link

lalitlogical commented Aug 28, 2015

+1 Nice!

@boomshadow

This comment has been minimized.

Copy link

boomshadow commented Sep 29, 2015

@springerigor Super +1! Thanks!

@KarthikRamu1

This comment has been minimized.

Copy link

KarthikRamu1 commented Oct 27, 2015

Thanks!

@TecnoSigma

This comment has been minimized.

Copy link

TecnoSigma commented Oct 30, 2015

Thanks!

@Banta

This comment has been minimized.

Copy link

Banta commented Nov 25, 2015

+1

@cheenwe

This comment has been minimized.

Copy link

cheenwe commented Dec 16, 2015

+1

@dmcwilliams

This comment has been minimized.

Copy link

dmcwilliams commented Dec 18, 2015

+1

@peter-trerotola

This comment has been minimized.

Copy link

peter-trerotola commented Jan 3, 2016

❤️

@petehamilton

This comment has been minimized.

Copy link

petehamilton commented Feb 10, 2016

❤️ perfect.

@lonny

This comment has been minimized.

Copy link

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 commented Mar 3, 2016

Like it 👍

@StephaneJuban

This comment has been minimized.

Copy link

StephaneJuban commented Apr 9, 2016

+1

@sakares

This comment has been minimized.

Copy link

sakares commented Apr 14, 2016

+1

@renandanton

This comment has been minimized.

Copy link

renandanton commented Jul 3, 2016

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

@Madh93

This comment has been minimized.

Copy link

Madh93 commented Aug 1, 2016

Like a charm 👍

@whrishi

This comment has been minimized.

Copy link

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 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 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 commented Oct 1, 2016

+1

@Andoresu250

This comment has been minimized.

Copy link

Andoresu250 commented Dec 12, 2016

+1

@lonny

This comment has been minimized.

Copy link

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 commented Mar 6, 2017

+1

@lppedrohs

This comment has been minimized.

Copy link

lppedrohs commented Mar 13, 2017

+1

@Evanto

This comment has been minimized.

Copy link

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 commented Jul 19, 2017

+1

@kinnrot

This comment has been minimized.

Copy link

kinnrot commented Jul 19, 2017

+3

@guillermoap

This comment has been minimized.

Copy link

guillermoap commented Jul 21, 2017

+1

@Aminbhs

This comment has been minimized.

Copy link

Aminbhs commented Aug 26, 2017

+1

@redbar0n

This comment has been minimized.

Copy link

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 commented Nov 20, 2017

+1

@tangens

This comment has been minimized.

Copy link

tangens commented Jan 17, 2018

+1

@RemiDuvoux

This comment has been minimized.

Copy link

RemiDuvoux commented Feb 23, 2018

+1

@iGEL

This comment has been minimized.

Copy link

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 commented Mar 22, 2018

+1

@joerzepiejewski

This comment has been minimized.

Copy link

joerzepiejewski commented May 9, 2018

👍

@dblock

This comment has been minimized.

Copy link

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 commented Sep 6, 2018

+1

@eliasdouglas

This comment has been minimized.

Copy link

eliasdouglas commented Feb 19, 2019

+1

@dhurba87

This comment has been minimized.

Copy link

dhurba87 commented Feb 21, 2019

+1

@YoshitsuguFujii

This comment has been minimized.

Copy link

YoshitsuguFujii commented Mar 15, 2019

+1

@alexwebgr

This comment has been minimized.

Copy link

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 commented Jun 24, 2019

👍

@MelvynSwingler

This comment has been minimized.

Copy link

MelvynSwingler commented Jul 15, 2019

This is pretty cool!

@itssomething

This comment has been minimized.

Copy link

itssomething commented Aug 7, 2019

👍

@pmichaeljones

This comment has been minimized.

Copy link

pmichaeljones commented Nov 26, 2019

Solid!

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.