JavaScript seconds to time string with format hh:mm:ss

574,588

Solution 1

String.prototype.toHHMMSS = function () {
    var sec_num = parseInt(this, 10); // don't forget the second param
    var hours   = Math.floor(sec_num / 3600);
    var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
    var seconds = sec_num - (hours * 3600) - (minutes * 60);

    if (hours   < 10) {hours   = "0"+hours;}
    if (minutes < 10) {minutes = "0"+minutes;}
    if (seconds < 10) {seconds = "0"+seconds;}
    return hours+':'+minutes+':'+seconds;
}

You can use it now like:

alert("5678".toHHMMSS());

Working snippet:

String.prototype.toHHMMSS = function () {
    var sec_num = parseInt(this, 10); // don't forget the second param
    var hours   = Math.floor(sec_num / 3600);
    var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
    var seconds = sec_num - (hours * 3600) - (minutes * 60);

    if (hours   < 10) {hours   = "0"+hours;}
    if (minutes < 10) {minutes = "0"+minutes;}
    if (seconds < 10) {seconds = "0"+seconds;}
    return hours + ':' + minutes + ':' + seconds;
}
    
console.log("5678".toHHMMSS());

Solution 2

You can manage to do this without any external JS library with the help of JS Date method like following:

var date = new Date(0);
date.setSeconds(45); // specify value for SECONDS here
var timeString = date.toISOString().substr(11, 8);
console.log(timeString)

Solution 3

To get the time part in the format hh:MM:ss, you can use this regular expression:

(This was mentioned above in same post by someone, thanks for that.)

    var myDate = new Date().toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");
    console.log(myDate)

Solution 4

I recommend ordinary javascript, using the Date object. (For a shorter solution, using toTimeString, see the second code snippet.)

var seconds = 9999;
// multiply by 1000 because Date() requires miliseconds
var date = new Date(seconds * 1000);
var hh = date.getUTCHours();
var mm = date.getUTCMinutes();
var ss = date.getSeconds();
// If you were building a timestamp instead of a duration, you would uncomment the following line to get 12-hour (not 24) time
// if (hh > 12) {hh = hh % 12;}
// These lines ensure you have two-digits
if (hh < 10) {hh = "0"+hh;}
if (mm < 10) {mm = "0"+mm;}
if (ss < 10) {ss = "0"+ss;}
// This formats your string to HH:MM:SS
var t = hh+":"+mm+":"+ss;
document.write(t);

(Of course, the Date object created will have an actual date associated with it, but that data is extraneous, so for these purposes, you don't have to worry about it.)


Edit (short solution):

Make use of the toTimeString function and split on the whitespace:

var seconds = 9999; // Some arbitrary value
var date = new Date(seconds * 1000); // multiply by 1000 because Date() requires miliseconds
var timeStr = date.toTimeString().split(' ')[0];

toTimeString gives '16:54:58 GMT-0800 (PST)', and splitting on the first whitespace gives '16:54:58'.

Solution 5

A Google search turned up this result:

function secondsToTime(secs)
{
    secs = Math.round(secs);
    var hours = Math.floor(secs / (60 * 60));

    var divisor_for_minutes = secs % (60 * 60);
    var minutes = Math.floor(divisor_for_minutes / 60);

    var divisor_for_seconds = divisor_for_minutes % 60;
    var seconds = Math.ceil(divisor_for_seconds);

    var obj = {
        "h": hours,
        "m": minutes,
        "s": seconds
    };
    return obj;
}
Share:
574,588
medk
Author by

medk

Updated on July 08, 2022

Comments

  • medk
    medk almost 2 years

    I want to convert a duration of time, i.e., number of seconds to colon-separated time string (hh:mm:ss)

    I found some useful answers here but they all talk about converting to x hours and x minutes format.

    So is there a tiny snippet that does this in jQuery or just raw JavaScript?

  • alunsford3
    alunsford3 almost 12 years
    Thanks for the prototype idea, I like how it is easier to call it. I prototyped the Number so I can call it on them too. I also found this answer that would remove the hours and minutes if they were not needed.
  • emmanuel honore
    emmanuel honore over 11 years
    I think this function is a feature used in the fronted and therefor I prototype String and not Number. And Number can always be a string but not the other way round.
  • Topher Fangio
    Topher Fangio almost 11 years
    +1 - Super-simple; thanks! Just used a variant of this to only show the minutes and seconds: var myDate = new Date().toTimeString().replace(/.*(\d{2}:\d{2})(:\d{2}).*/, "$1");
  • mivk
    mivk almost 11 years
    It seems to make the date in the local time zone, which in my case adds 1 hour to the time. With seconds=0, I get "01:00:00" (Thu Jan 01 1970 01:00:00 GMT+0100 (CET)), which is wrong.
  • mivk
    mivk almost 11 years
    I get a correct result if I use date.getUTCHours() and date.getUTCMinutes().
  • simey.me
    simey.me over 10 years
    wow, this is amazing! I hate dealing with time in javascript.
  • obie
    obie over 10 years
    shouldn't that be "new Date(null, null, null, null, null, timeInSecs).toTimeString().replace(/.*(\d{2}:)(\d{2}:\d{2}).‌​*/, "$2")" ?
  • starsinmypockets
    starsinmypockets over 10 years
    Thanks for saving me an hour on this
  • Benjamin Crouzier
    Benjamin Crouzier over 10 years
    secondsToTime(119.9) => Object {h: 0, m: 1, s: 60}. To fix this, add secs = Math.round(secs); at the beginning of the method. Of course, we saw this bug during the demo...
  • caesarsol
    caesarsol over 10 years
    I think Number is right because seconds is, in fact, a number. you should convert from string before using this function, which is the right thing to do!
  • Călin Darie
    Călin Darie over 10 years
    The use of replace is confusing. Why not use new Date(null, null, null, null, null, timeInSeconds).toTimeString().match(/\d{2}:\d{2}:\d{2}/)[0] ?
  • DA.
    DA. over 10 years
    Just wondering...any particular reason to be passing the seconds in as a string rather than integer?
  • emmanuel honore
    emmanuel honore over 10 years
    @DA. String will work for Number as well but the other way round not.
  • IvanM
    IvanM about 10 years
    use "%" operator >> var minutes = Math.floor((sec_num % 3600) / 60); var seconds = Math.floor(sec_num % 60);
  • mahemoff
    mahemoff over 9 years
    This is fine for showing a given time, but note the question (and other answers here) are about showing a duration, i.e. a given number of seconds independent of the current time.
  • Emil Borconi
    Emil Borconi over 9 years
    Why is this answer with so low? I get it in 2011 probably IE 7 and 8 was the base which will not support it, but it's end of 2014, so this simple plain, fuss free solution should be way higher.
  • Nathan C. Tresch
    Nathan C. Tresch about 9 years
    I don't understand why you're returning a 12 hour timestamp when he asked for a duration?
  • Nathan C. Tresch
    Nathan C. Tresch about 9 years
    @JellicleCat Changed to a +1, and nice name.
  • Andrew
    Andrew about 9 years
    From MDN: If a parameter you specify is outside of the expected range, setSeconds() attempts to update the date information in the Date object accordingly. For example, if you use 100 for secondsValue, the minutes stored in the Date object will be incremented by 1, and 40 will be used for seconds. So yeah, looks good!
  • IpsRich
    IpsRich about 9 years
    Nice - thanks! And a small improvement I made for my needs was to convert a duration in milliseconds to HH:MM:SS -- new Date(new Date().getTime() - startTime).toUTCString().split(" ")[4] where startTime was set previously using startTime = new Date().getTime();. (I had to use toUTCString() because otherwise the times were an hour out.)
  • Sonic Soul
    Sonic Soul almost 9 years
    awesome idea! just curious why string and not Number prototype? since seconds are usually an int and would need to be converted toString. This works for me ((date2 - date1) / 1000).secondsToTimespan()
  • emmanuel honore
    emmanuel honore almost 9 years
  • Sonic Soul
    Sonic Soul almost 9 years
    ah thanks. I don't see it working both ways as a string until you call .toString() on the integer. you can make it work the other way around by parsing int too
  • puppeteer701
    puppeteer701 over 8 years
    how would we have to change regex so it generates hh:MM?
  • Michael J. Calkins
    Michael J. Calkins over 8 years
    Don't put in on the prototype, just make a utility function.
  • David Clarke
    David Clarke over 8 years
    new Date().toTimeString().replace(/^(\d{2}:\d{2}).*/, "$1") can be used for hh:MM - note the original regex begins with /.*. This is a greedy match and will match minutes and seconds rather than hours and minutes. Using /^ forces the regex to match at the beginning of the string.
  • cjbarth
    cjbarth over 8 years
    This only works if your time duration is less than 1 day. But otherwise, pretty nice.
  • Charlie Martin
    Charlie Martin over 8 years
    This will be incorrect for durations of 24 days or longer
  • Eirik Birkeland
    Eirik Birkeland about 8 years
    Doesn't answer the question.
  • Matstar
    Matstar about 8 years
    Simpler version of this: new Date().toTimeString().split(" ")[0]
  • Learning-Overthinker-Confused
    Learning-Overthinker-Confused almost 8 years
    I have two datetime object and and i want to calculate difference of this 2 datetime object and return output like in this format :Hour : Minutes :Seconds with double digit like : 01 : 02 : 45.Can you please tell me or guide me little with your code??
  • Bohumir Zamecnik
    Bohumir Zamecnik over 7 years
    I like this answer. It can be even shorter: new Date(1000 * seconds).toISOString().substr(11, 8).
  • Winter
    Winter over 7 years
    I'd put a Math.floor() on the seconds as well since they might be given in decimals. (Happened with me.)
  • Ole V.V.
    Ole V.V. over 7 years
    Kind of you. Not really providing anything substantial that hasn’t been given in one or more of the 30 answers already.
  • phpFreak
    phpFreak over 7 years
    indeed, juist a trying to help to keep it simple
  • Nguyễn Anh Tuấn
    Nguyễn Anh Tuấn over 7 years
    Very simple. Thank you so much.
  • Dustin Graham
    Dustin Graham over 7 years
    Note: Doesn't work quite right on negative time. (My timer starts at -60 seconds counting towards zero to "start" then continues after that.)
  • Palo
    Palo about 7 years
    Nice answer. You can use .replace(/^[0:]+/, "") after substr to remove all zeroes and : from the start of the string.
  • Josh Burgess
    Josh Burgess about 7 years
    Further explanation on why this answer would work for the questioner or what may have been wrong in the original question would help raise the quality of this answer.
  • Lukas Liesis
    Lukas Liesis almost 7 years
    modify prototype for such thing? 390 upvotes? seriously?
  • Lukas Liesis
    Lukas Liesis almost 7 years
    upvoted answer, just like this one, are bad. I bet you don't need ALL numbers to have this method. Do not modify prototype for random utility stuff.
  • Pi Home Server
    Pi Home Server over 6 years
    Works like a charm (except format that is not defined) to convert a duration in an object with months, days, hours, minutes and seconds
  • AlexioVay
    AlexioVay over 6 years
    Pretty self explainatory and good answer, reduced and simplified the top answer.
  • Ruben Stolk
    Ruben Stolk over 6 years
    You could write this as: const formatTime = (seconds, h = Math.floor(seconds / 3600), m = Math.floor((seconds % 3600) / 60), s = seconds % 60) => [h, m > 9 ? m : '0' + m, s > 9 ? s : '0' + s].filter(s => s).join(':');
  • Tom Esterez
    Tom Esterez over 6 years
    @RubenStolk I find it a bit confusing to have a function that takes two second arguments. I find my version clearer even if it's a bit more verbose.
  • irag10
    irag10 about 6 years
    I like this, but it does assume the duration is less than 24h
  • Jimmy Kane
    Jimmy Kane about 6 years
    why are you comparing strings greater of 0?
  • Ronnie Royston
    Ronnie Royston almost 6 years
    to knock out the hh: if the time is less than an hour, if(result.length === 8 && result.substring(0,3) === "00:"){ return result.substr(3); } else { return result; }
  • Olian04
    Olian04 almost 6 years
    seconds: number type annotations, in es6?
  • Brynner Ferreira
    Brynner Ferreira over 5 years
    Really Awesome. Congrats!
  • Jeffz
    Jeffz over 5 years
    Nice ... and >24 hrs safe.
  • yeahdixon
    yeahdixon over 5 years
    or just to prototype and make it a function numToHHMMSS or strTOHHMMSS
  • Rishav Kumar
    Rishav Kumar about 5 years
    Precise Answer : )
  • Umesh Patadiya
    Umesh Patadiya about 5 years
    How can I do revert operation?
  • nïkö
    nïkö about 5 years
    @JimmyKane because automatic typecasting - i looove it! (plus: code is more easy to read (you've got typecasting for a reason, but let's stop trolling (the both of us)). plus: the function would fail only if t is NaN - so if you want security: do it at the input!)
  • Jimmy Kane
    Jimmy Kane about 5 years
    @nïkö Ok I understand but more strict new JS versions , linters etc can complain about that. Just saying, dong get me wrong. I like your answer
  • Duoc Tran
    Duoc Tran almost 5 years
    I hope this is not how CS is taught at uni these days. The most voted answer is the one that takes a NUMBER of seconds as a string then parseInt() it to be able to do the calculations. Seriously. If you deal with days' worth of seconds or negative number, see stackoverflow.com/a/55896694/2028733.
  • Johann
    Johann almost 5 years
    This will fail for certain values and seconds end up showing up as 60. Example 00:14:60. Surprised with the high number of up votes on this solution and nobody seemed to actually test it out thoroughly.
  • Johann
    Johann almost 5 years
    This solution works while the chosen solution generates seconds of 60 for certain values.
  • emmanuel honore
    emmanuel honore almost 5 years
    @AndroidDev it does not. Have a look at this test: jsfiddle.net/powtac/1aoLqpr4 it outputs 00:14:59 and 00:15:00. No way to trigger your result.
  • emmanuel honore
    emmanuel honore almost 5 years
    @DuocTran Most values, especially when extracted from HTML or for example JSON are strings, because they can be only transmitted as strings. So it's natural to start with reading strings, then in the function parsing the value into int. So the both most common use cases (string and pure int) are covered. No need for the user to differentiate a type value here.
  • mrdaliri
    mrdaliri almost 5 years
    I think the OP wants to convert a duration (seconds) not a Date object.
  • DataGreed
    DataGreed over 4 years
    oops, my bad :(
  • Tofandel
    Tofandel over 4 years
    Add parseInt(d / 86400) + "d " in front to handle cases over 24h
  • Tofandel
    Tofandel over 4 years
    Add this in front to handle time over 24h. parseInt(d / 86400) + "d "
  • Tofandel
    Tofandel over 4 years
    To get elapsed time from this use new Date(time*1000).toISOString().replace(/.*(\d{2}:\d{2}:\d{2})‌​.*/, "$1"); don't use toTimeString or you'll get GMT offset issues
  • pstanton
    pstanton about 4 years
    you've got a superfluous comma at end of: s > 9 ? s : '0' + s,
  • Tom Esterez
    Tom Esterez about 4 years
    @pstanton trailing comma are legit in JS. I do prefer having them so it's easier to add/remove/move lines: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • pstanton
    pstanton about 4 years
    @TomEsterez cause syntax errors in earlier browsers - so subjective at best
  • Tom Esterez
    Tom Esterez about 4 years
    @pstanton trailing comma is supported since IE9: caniuse.com/#feat=mdn-javascript_grammar_trailing_commas . I personally choose to ignore those old browsers now. But you're right, I removed it so the answer is more generic.
  • Raff
    Raff about 4 years
    Great solution. Maybe just change seconds as const s = Math.round(seconds % 60);
  • Tom Esterez
    Tom Esterez about 4 years
    @Raff, the modulo (%) already returns an integer value so Math.round is not necessary.
  • Tom Esterez
    Tom Esterez about 4 years
    Actually, you're right. The input seconds could have decimals. So I'll change it 👍
  • Esten
    Esten about 4 years
    @Palo that is unnecessary, as substr is selecting a segment of the string. You could simply modify the arguments to select the portion of the string you would like to keep. That said, substr is being phased out for substring, and furthermore slice is a very similar method that would probably be more suited to use in your codebase as it is generally more popular in the wild.
  • Matt Kenefick
    Matt Kenefick almost 4 years
    Great solution. Adding this obvious bit for those that don't know: If you want only mm:ss, then you change the substr to this: var timeString = date.toISOString().substr(14, 5);
  • Barney Szabolcs
    Barney Szabolcs almost 4 years
    @LukasLiesis Yeah, this does not look good at all. Also, it should not use String but Int input... the other answer is way better. I think the issue is that we cannot take back our vote. Stackoverflow says: "You last voted on this answer 9 mins ago. Your vote is now locked in unless this answer is edited."
  • Lukas Liesis
    Lukas Liesis almost 4 years
    @Barney just edited the answer to run as a helper function.
  • sim642
    sim642 over 3 years
    This breaks if the duration is longer than 23:59:59.
  • maxime1992
    maxime1992 over 3 years
    FYI this is modulo 24h so if you input the equivalent of 25 hours it'll appear as 1 hour. Be careful
  • Ryan Leach
    Ryan Leach over 3 years
    Timezones hate this.
  • Ryan Leach
    Ryan Leach over 3 years
    Timezones hate this. question is about converting seconds into a duration.
  • Cedric Ipkiss
    Cedric Ipkiss almost 3 years
    This should be a comment under an answer
  • Tim
    Tim almost 3 years
    If the time is larger than 24 hours (86400 seconds), this is going to give wrong results
  • akirk
    akirk over 2 years
    This is amazingly clever. Thanks!
  • N. Arunoprayoch
    N. Arunoprayoch over 2 years
    Thanks, this is exactly what I was looking for. Just like Youtube's.
  • Amir Savand
    Amir Savand over 2 years
    This is great, I turned it into an angular pipe for my project. @Pipe({ name: 'duration' }) export class DurationPipe implements PipeTransform { transform(value: number): string { const date = new Date(0); date.setSeconds(value); return date.toISOString().substr(11, 8); } }
  • Aaron B
    Aaron B over 2 years
    Short and sweet, very good. Suggest replacing parseInt with Math.floor esp. if using TypeScript (parseInt should have string input)
  • Pythonista
    Pythonista over 2 years
    @HenrikN Date().split [4] if you want to golf for current HH:MM:SS format. Can be reduced further if aliasing builtins of course.
  • Matstar
    Matstar over 2 years
    Thanks, @Pythonista. That doesn't work as-is for me but Date().split(" ")[4] does.
  • Pythonista
    Pythonista over 2 years
    @HenrikN The comment was messed up. There should be two back ticks after the split. Code golf thing. You don't need the parenthesis. Swap the " for ticks
  • Lee Goddard
    Lee Goddard about 2 years
    parseInt requires a string, so seconds must be a string. In TypeScript, if seconds is a number, use Math.floor instead of parseInt.