JavaScript seconds to time string with format hh:mm:ss
Asked Answered
Z

48

419

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?

Zinck answered 10/6, 2011 at 23:23 Comment(2)
Benchmarks of a few of the suggested answers in this thread. jsperf.com/ms-to-hh-mm-ss-time-formatCrin
Possible duplicate of Convert seconds to HH-MM-SS with JavaScript?Haynor
S
708
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());
Shad answered 10/6, 2011 at 23:27 Comment(18)
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.Gibbet
Just wondering...any particular reason to be passing the seconds in as a string rather than integer?Bregenz
@Bregenz String will work for Number as well but the other way round not.Shad
use "%" operator >> var minutes = Math.floor((sec_num % 3600) / 60); var seconds = Math.floor(sec_num % 60);Eisenstein
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()Manchu
@sonic-soul see #6313493Shad
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 tooManchu
Don't put in on the prototype, just make a utility function.Veronica
Note: Doesn't work quite right on negative time. (My timer starts at -60 seconds counting towards zero to "start" then continues after that.)Mortal
modify prototype for such thing? 390 upvotes? seriously?Senator
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; }Unscrupulous
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 https://mcmap.net/q/35665/-convert-seconds-to-hh-mm-ss-with-javascript.Hammer
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.Areola
@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.Shad
@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.Shad
@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."Frazee
@Barney just edited the answer to run as a helper function.Senator
Github copilot gave me a direct link to your answer after the query // function to get date in the correct timezone. Not relevant to anything but thought it was interesting.Atli
R
371

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().substring(11, 19);
console.log(timeString)
Ronen answered 13/8, 2014 at 6:26 Comment(10)
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.Crowned
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!Detrital
I like this answer. It can be even shorter: new Date(1000 * seconds).toISOString().substr(11, 8).Lowbred
Nice answer. You can use .replace(/^[0:]+/, "") after substr to remove all zeroes and : from the start of the string.Cami
Add this in front to handle time over 24h. parseInt(d / 86400) + "d "Crayton
@Cami 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.Attenuant
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);Dietrich
This breaks if the duration is longer than 23:59:59.Rahn
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); } }Diarthrosis
Bohumir's comment, but without deprecated substr: new Date(1000 * seconds).toISOString().substring(11, 19)Hiett
H
84

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)
Hipped answered 27/9, 2012 at 1:22 Comment(15)
+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");Chewink
shouldn't that be "new Date(null, null, null, null, null, timeInSecs).toTimeString().replace(/.*(\d{2}:)(\d{2}:\d{2}).*/, "$2")" ?Sulfaguanidine
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] ?Rosa
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.Mug
how would we have to change regex so it generates hh:MM?Buerger
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.Tertial
Doesn't answer the question.Resonator
Simpler version of this: new Date().toTimeString().split(" ")[0]Doviedow
Very simple. Thank you so much.Mair
How can I do revert operation?Cholecystectomy
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 issuesCrayton
@HenrikN Date().split [4] if you want to golf for current HH:MM:SS format. Can be reduced further if aliasing builtins of course.Presumable
Thanks, @Pythonista. That doesn't work as-is for me but Date().split(" ")[4] does.Doviedow
@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 ticksPresumable
If you use toTimeString in my timezone, you get one hour extra with console.log(new Date(600000).toTimeString().split(" ")[0])Crock
L
63

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'.

Lancastrian answered 10/6, 2011 at 23:32 Comment(9)
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.Tiling
I get a correct result if I use date.getUTCHours() and date.getUTCMinutes().Tiling
I don't understand why you're returning a 12 hour timestamp when he asked for a duration?Harty
@JellicleCat Changed to a +1, and nice name.Harty
I like this, but it does assume the duration is less than 24hBeatnik
Add parseInt(d / 86400) + "d " in front to handle cases over 24hCrayton
Timezones hate this.Guyguyana
yep, the short solution does NOT work with daylight savings. It will add an hour.Cyclo
This seems to fix that issue: const seconds = 9999; const date = new Date(Date.UTC(0, 0, 0, 0, 0, seconds)); const timeStr = date.toTimeString().split(' ')[0]; or even better, use toLocaleTimeString and then you don't need to split it: const seconds = 9999; const date = new Date(Date.UTC(0, 0, 0, 0, 0, seconds)); const timeStr = date.toLocaleTimeString('UTC');Cyclo
T
55

Here's my take on it:

function formatTime(ms: number) {
  const seconds = Math.floor(Math.abs(ms / 1000))
  const h = Math.floor(seconds / 3600)
  const m = Math.floor((seconds % 3600) / 60)
  const s = Math.round(seconds % 60)
  const t = [h, m > 9 ? m : h ? '0' + m : m || '0', s > 9 ? s : '0' + s]
    .filter(Boolean)
    .join(':')
  return ms < 0 && seconds ? `-${t}` : t
}

Expected results:

import assert from 'assert'
assert.equal(formatTime(0), '0:00')
assert.equal(formatTime(1_000), '0:01')
assert.equal(formatTime(599_000), '9:59')
assert.equal(formatTime(600_000), '10:00')
assert.equal(formatTime(3600_000), '1:00:00')
assert.equal(formatTime(360009_000), '100:00:09')
assert.equal(formatTime(200), '0:00')
assert.equal(formatTime(-200), '0:00')
assert.equal(formatTime(-1_000), '-0:01')
Tineid answered 31/10, 2016 at 20:23 Comment(11)
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(':');Schnabel
@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.Tineid
seconds: number type annotations, in es6?Eweneck
you've got a superfluous comma at end of: s > 9 ? s : '0' + s,Nuno
@Nuno 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/…Tineid
@TomEsterez cause syntax errors in earlier browsers - so subjective at bestNuno
@Nuno 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.Tineid
Great solution. Maybe just change seconds as const s = Math.round(seconds % 60);Find
@Raff, the modulo (%) already returns an integer value so Math.round is not necessary.Tineid
Actually, you're right. The input seconds could have decimals. So I'll change it 👍Tineid
Thanks, this is exactly what I was looking for. Just like Youtube's.Krummhorn
T
45

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;
}
Treehopper answered 10/6, 2011 at 23:25 Comment(1)
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...Creole
R
33
function formatTime(seconds) {
    return [
        parseInt(seconds / 60 / 60),
        parseInt(seconds / 60 % 60),
        parseInt(seconds % 60)
    ]
        .join(":")
        .replace(/\b(\d)\b/g, "0$1")
}
Roddie answered 18/4, 2017 at 7:58 Comment(6)
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.Messalina
Pretty self explainatory and good answer, reduced and simplified the top answer.Musil
Precise Answer : )Boraginaceous
Short and sweet, very good. Suggest replacing parseInt with Math.floor esp. if using TypeScript (parseInt should have string input)Malvie
parseInt requires a string, so seconds must be a string. In TypeScript, if seconds is a number, use Math.floor instead of parseInt.Hypno
Suggestion: remove the parseInt and instead place .map(Math.floor) before .join(':'). Also, for better readability, instead of .replace(/\b(\d)\b/g, "0$1") after the .join(), one could use .map(n => n.toString().padStart(2, '0')) before the .join().Tallage
M
32

Variation on a theme. Handles single digit seconds a little differently

seconds2time(0)  ->  "0s" 
seconds2time(59) -> "59s" 
seconds2time(60) -> "1:00" 
seconds2time(1000) -> "16:40" 
seconds2time(4000) -> "1:06:40"

function seconds2time (seconds) {
    var hours   = Math.floor(seconds / 3600);
    var minutes = Math.floor((seconds - (hours * 3600)) / 60);
    var seconds = seconds - (hours * 3600) - (minutes * 60);
    var time = "";

    if (hours != 0) {
      time = hours+":";
    }
    if (minutes != 0 || time !== "") {
      minutes = (minutes < 10 && time !== "") ? "0"+minutes : String(minutes);
      time += minutes+":";
    }
    if (time === "") {
      time = seconds+"s";
    }
    else {
      time += (seconds < 10) ? "0"+seconds : String(seconds);
    }
    return time;
}
Maebashi answered 28/9, 2011 at 7:37 Comment(0)
C
15

I like the first answer. There some optimisations:

  • source data is a Number. additional calculations is not needed.

  • much excess computing

Result code:

Number.prototype.toHHMMSS = function () {
    var seconds = Math.floor(this),
        hours = Math.floor(seconds / 3600);
    seconds -= hours*3600;
    var minutes = Math.floor(seconds / 60);
    seconds -= minutes*60;

    if (hours   < 10) {hours   = "0"+hours;}
    if (minutes < 10) {minutes = "0"+minutes;}
    if (seconds < 10) {seconds = "0"+seconds;}
    return hours+':'+minutes+':'+seconds;
}
Chorister answered 13/11, 2012 at 20:36 Comment(5)
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.Shad
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!Conformance
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.Senator
or just to prototype and make it a function numToHHMMSS or strTOHHMMSSFaxan
This solution works while the chosen solution generates seconds of 60 for certain values.Areola
G
15

Using the amazing moment.js library:

function humanizeDuration(input, units ) { 
  // units is a string with possible values of y, M, w, d, h, m, s, ms
  var duration = moment().startOf('day').add(units, input),
    format = "";

  if(duration.hour() > 0){ format += "H [hours] "; }

  if(duration.minute() > 0){ format += "m [minutes] "; }

  format += " s [seconds]";

  return duration.format(format);
}

This allows you to specify any duration be it hours, minutes, seconds, mills, and returns a human readable version.

Gouty answered 18/5, 2013 at 20:41 Comment(0)
P
15

Here is an example of using Date.prototype.toLocaleTimeString(). I chose GB as the language, because the US shows a 24 instead of a 00 for the initial hour. Furthermore, I chose Etc/UTC as the time zone, because UTC is aliased to it in the list of tz database time zones.

const formatTime = (seconds) =>
  new Date(seconds * 1000).toLocaleTimeString('en-GB', {
    timeZone:'Etc/UTC',
    hour12: false,
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  });

console.log(formatTime(75)); // 00:01:15
.as-console-wrapper { top: 0; max-height: 100% !important; }

Here is the same example, but with Intl.DateTimeFormat. This variant lets you instantiate a reusable formatter object, which is more performant.

const dateFormatter = new Intl.DateTimeFormat('en-GB', {
  timeZone:'Etc/UTC',
  hour12: false,
  hour: '2-digit',
  minute: '2-digit',
  second: '2-digit'
});

const formatTime = (seconds) => dateFormatter.format(new Date(seconds * 1000));

console.log(formatTime(75)); // 00:01:15
.as-console-wrapper { top: 0; max-height: 100% !important; }
Pashm answered 9/6, 2021 at 15:17 Comment(2)
If the time is larger than 24 hours (86400 seconds), this is going to give wrong resultsThermogenesis
This is amazingly clever. Thanks!Profligate
R
14

It's pretty easy,

function toTimeString(seconds) {
  return (new Date(seconds * 1000)).toUTCString().match(/(\d\d:\d\d:\d\d)/)[0];
}
Recension answered 14/4, 2015 at 3:34 Comment(1)
This only works if your time duration is less than 1 day. But otherwise, pretty nice.Shulock
F
11

new Date().toString().split(" ")[4];

result 15:08:03

Ferula answered 8/8, 2013 at 12:55 Comment(1)
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.)Augustinaaugustine
J
11

Easiest way to do it.

new Date(sec * 1000).toISOString().substr(11, 8)
Jokester answered 27/7, 2020 at 7:49 Comment(1)
FYI this is modulo 24h so if you input the equivalent of 25 hours it'll appear as 1 hour. Be carefulUnderworld
M
8
s2t=function (t){
  return parseInt(t/86400)+'d '+(new Date(t%86400*1000)).toUTCString().replace(/.*(\d{2}):(\d{2}):(\d{2}).*/, "$1h $2m $3s");
}

s2t(123456);

result:

1d 10h 17m 36s
Martinmartina answered 10/10, 2013 at 15:31 Comment(0)
T
8

I liked Webjins answer the most, so i extended it to display days with a d suffix, made display conditional and included a s suffix on plain seconds:

function sec2str(t){
    var d = Math.floor(t/86400),
        h = ('0'+Math.floor(t/3600) % 24).slice(-2),
        m = ('0'+Math.floor(t/60)%60).slice(-2),
        s = ('0' + t % 60).slice(-2);
    return (d>0?d+'d ':'')+(h>0?h+':':'')+(m>0?m+':':'')+(t>60?s:s+'s');
}

returns "3d 16:32:12" or "16:32:12" or "32:12" or "12s"

Troup answered 13/2, 2015 at 23:12 Comment(4)
This will be incorrect for durations of 24 days or longerByyourleave
why are you comparing strings greater of 0?Stockbreeder
@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!)Oasis
@Troup Ok I understand but more strict new JS versions , linters etc can complain about that. Just saying, dong get me wrong. I like your answerStockbreeder
D
7

I loved Powtac's answer, but I wanted to use it in angular.js, so I created a filter using his code.

.filter('HHMMSS', ['$filter', function ($filter) {
    return function (input, decimals) {
        var sec_num = parseInt(input, 10),
            decimal = parseFloat(input) - sec_num,
            hours   = Math.floor(sec_num / 3600),
            minutes = Math.floor((sec_num - (hours * 3600)) / 60),
            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;}
        var time    = hours+':'+minutes+':'+seconds;
        if (decimals > 0) {
            time += '.' + $filter('number')(decimal, decimals).substr(2);
        }
        return time;
    };
}])

It's functionally identical, except that I added in an optional decimals field to display fractional seconds. Use it like you would any other filter:

{{ elapsedTime | HHMMSS }} displays: 01:23:45

{{ elapsedTime | HHMMSS : 3 }} displays: 01:23:45.678

Diffusive answered 28/10, 2014 at 23:9 Comment(1)
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??Calore
K
4

Here is yet another version, which handles days also:

function FormatSecondsAsDurationString( seconds )
{
    var s = "";

    var days = Math.floor( ( seconds / 3600 ) / 24 );
    if ( days >= 1 )
    {
        s += days.toString() + " day" + ( ( days == 1 ) ? "" : "s" ) + " + ";
        seconds -= days * 24 * 3600;
    }

    var hours = Math.floor( seconds / 3600 );
    s += GetPaddedIntString( hours.toString(), 2 ) + ":";
    seconds -= hours * 3600;

    var minutes = Math.floor( seconds / 60 );
    s += GetPaddedIntString( minutes.toString(), 2 ) + ":";
    seconds -= minutes * 60;

    s += GetPaddedIntString( Math.floor( seconds ).toString(), 2 );

    return s;
}

function GetPaddedIntString( n, numDigits )
{
    var nPadded = n;
    for ( ; nPadded.length < numDigits ; )
    {
        nPadded = "0" + nPadded;
    }

    return nPadded;
}
Kiddush answered 1/4, 2013 at 19:23 Comment(0)
H
4
function toHHMMSS(seconds) {
    var h, m, s, result='';
    // HOURs
    h = Math.floor(seconds/3600);
    seconds -= h*3600;
    if(h){
        result = h<10 ? '0'+h+':' : h+':';
    }
    // MINUTEs
    m = Math.floor(seconds/60);
    seconds -= m*60;
    result += m<10 ? '0'+m+':' : m+':';
    // SECONDs
    s=seconds%60;
    result += s<10 ? '0'+s : s;
    return result;
}

Examples

    toHHMMSS(111); 
    "01:51"

    toHHMMSS(4444);
    "01:14:04"

    toHHMMSS(33);
    "00:33"
Henderson answered 10/4, 2014 at 11:34 Comment(1)
I'd put a Math.floor() on the seconds as well since they might be given in decimals. (Happened with me.)Pagination
N
4

The most general answer to this is

function hms(seconds) {
  return [3600, 60]
    .reduceRight(
      (p, b) => r => [Math.floor(r / b)].concat(p(r % b)),
      r => [r]
    )(seconds)
    .map(a => a.toString().padStart(2, '0'))
    .join(':');
}

Some example outputs:

> hms(0)
< "00:00:00"

> hms(5)
< "00:00:05"

> hms(60)
< "00:01:00"

> hms(3785)
< "01:03:05"

> hms(37850)
< "10:30:50"

> hms(378500)
< "105:08:20"

See explanation at https://mcmap.net/q/35665/-convert-seconds-to-hh-mm-ss-with-javascript

Natality answered 6/3, 2021 at 11:6 Comment(0)
A
4
function secToTime(seconds, separator) {
    return [
        parseInt(seconds / 60 / 60),
        parseInt(seconds / 60 % 60),
        parseInt(seconds % 60)
    ].join(separator ? separator : ':')
    .replace(/\b(\d)\b/g, "0$1").replace(/^00\:/,'')
}

You can use it now like:

alert(secToTime("123"));

Working snippet:

function secToTime(seconds, separator) {
return [
    parseInt(seconds / 60 / 60),
    parseInt(seconds / 60 % 60),
    parseInt(seconds % 60)
].join(separator ? separator : ':')
.replace(/\b(\d)\b/g, "0$1").replace(/^00\:/,'')
}

console.log(secToTime("123"));
Amber answered 19/2, 2022 at 12:12 Comment(0)
P
3

I think performance wise this is by far the fastest:

var t = 34236; // your seconds
var time = ('0'+Math.floor(t/3600) % 24).slice(-2)+':'+('0'+Math.floor(t/60)%60).slice(-2)+':'+('0' + t % 60).slice(-2)
//would output: 09:30:36
Pendant answered 3/12, 2013 at 13:3 Comment(2)
Really Awesome. Congrats!Dara
Nice ... and >24 hrs safe.Motherinlaw
F
2

A regular expression can be used to match the time substring in the string returned from the toString() method of the Date object, which is formatted as follows: "Thu Jul 05 2012 02:45:12 GMT+0100 (GMT Daylight Time)". Note that this solution uses the time since the epoch: midnight of January 1, 1970. This solution can be a one-liner, though splitting it up makes it much easier to understand.

function secondsToTime(seconds) {
    const start = new Date(1970, 1, 1, 0, 0, 0, 0).getTime();
    const end = new Date(1970, 1, 1, 0, 0, parseInt(seconds), 0).getTime();
    const duration = end - start;

    return new Date(duration).toString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");
}
Fervid answered 5/7, 2012 at 2:2 Comment(1)
Timezones hate this. question is about converting seconds into a duration.Guyguyana
I
2

Here's how I did it. It seems to work fairly well, and it's extremely compact. (It uses a lot of ternary operators, though)

function formatTime(seconds) {
  var hh = Math.floor(seconds / 3600),
    mm = Math.floor(seconds / 60) % 60,
    ss = Math.floor(seconds) % 60;
  return (hh ? (hh < 10 ? "0" : "") + hh + ":" : "") + ((mm < 10) && hh ? "0" : "") + mm + ":" + (ss < 10 ? "0" : "") + ss
}

...and for formatting strings...

String.prototype.toHHMMSS = function() {
  formatTime(parseInt(this, 10))
};
Ieshaieso answered 20/1, 2014 at 23:33 Comment(0)
O
2

You can use the following function to convert time (in seconds) to HH:MM:SS format :

var convertTime = function (input, separator) {
    var pad = function(input) {return input < 10 ? "0" + input : input;};
    return [
        pad(Math.floor(input / 3600)),
        pad(Math.floor(input % 3600 / 60)),
        pad(Math.floor(input % 60)),
    ].join(typeof separator !== 'undefined' ?  separator : ':' );
}

Without passing a separator, it uses : as the (default) separator :

time = convertTime(13551.9941351); // --> OUTPUT = 03:45:51

If you want to use - as a separator, just pass it as the second parameter:

time = convertTime(1126.5135155, '-'); // --> OUTPUT = 00-18-46

Demo

var convertTime = function (input, separator) {
    var pad = function(input) {return input < 10 ? "0" + input : input;};
    return [
        pad(Math.floor(input / 3600)),
        pad(Math.floor(input % 3600 / 60)),
        pad(Math.floor(input % 60)),
    ].join(typeof separator !== 'undefined' ?  separator : ':' );
}

document.body.innerHTML = '<pre>' + JSON.stringify({
    5.3515555 : convertTime(5.3515555),
    126.2344452 : convertTime(126.2344452, '-'),
    1156.1535548 : convertTime(1156.1535548, '.'),
    9178.1351559 : convertTime(9178.1351559, ':'),
    13555.3515135 : convertTime(13555.3515135, ',')
}, null, '\t') +  '</pre>';

See also this Fiddle.

Overprize answered 24/2, 2017 at 12:12 Comment(0)
S
2

There's a new method for strings on the block: padStart

const str = '5';
str.padStart(2, '0'); // 05

Here is a sample use case: YouTube durations in 4 lines of JavaScript

Said answered 14/1, 2018 at 20:2 Comment(1)
This should be a comment under an answerKarakalpak
D
2

const secondsToTime = (seconds, locale) => {
    const date = new Date(0);
    date.setHours(0, 0, seconds, 0);
    return date.toLocaleTimeString(locale);
}
console.log(secondsToTime(3610, "en"));

where the locale parameter ("en", "de", etc.) is optional

Depurative answered 19/3, 2018 at 8:32 Comment(0)
A
2

Here is a fairly simple solution that rounds to the nearest second!

var returnElapsedTime = function(epoch) {
  //We are assuming that the epoch is in seconds
  var hours = epoch / 3600,
      minutes = (hours % 1) * 60,
      seconds = (minutes % 1) * 60;
  return Math.floor(hours) + ":" + Math.floor(minutes) + ":" + Math.round(seconds);
}
Albric answered 19/12, 2019 at 16:36 Comment(0)
D
2

This is one I wrote recently for MM:SS. It's not exact to the question, but it's a different one-liner format.

const time = 60 * 2 + 35; // 2 minutes, 35 seconds
const str = (~~(time / 60) + "").padStart(2, '0') + ":" + (~~((time / 60) % 1 * 60) + "").padStart(2, '0');

str // 02:35

Edit: This was added for variety, but the best solution here is https://mcmap.net/q/35589/-javascript-seconds-to-time-string-with-format-hh-mm-ss below.

Dietrich answered 21/4, 2020 at 19:35 Comment(0)
P
1

This is how i did it

function timeFromSecs(seconds)
{
    return(
    Math.floor(seconds/86400)+'d :'+
    Math.floor(((seconds/86400)%1)*24)+'h : '+
    Math.floor(((seconds/3600)%1)*60)+'m : '+
    Math.round(((seconds/60)%1)*60)+'s');
}

timeFromSecs(22341938) will return '258d 14h 5m 38s'

Pencil answered 17/4, 2013 at 10:28 Comment(0)
W
1

I'm personally prefer the leading unit (days, hours, minutes) without leading zeros. But seconds should always be leaded by minutes (0:13), this presentation is easily considered as 'duration', without further explanation (marking as min, sec(s), etc.), usable in various languages (internationalization).

    // returns  (-)d.h:mm:ss(.f)
    //          (-)h:mm:ss(.f)
    //          (-)m:ss(.f)
    function formatSeconds (value, fracDigits) {
        var isNegative = false;
        if (isNaN(value)) {
            return value;
        } else if (value < 0) {
            isNegative = true;
            value = Math.abs(value);
        }
        var days = Math.floor(value / 86400);
        value %= 86400;
        var hours = Math.floor(value / 3600);
        value %= 3600;
        var minutes = Math.floor(value / 60);
        var seconds = (value % 60).toFixed(fracDigits || 0);
        if (seconds < 10) {
            seconds = '0' + seconds;
        }

        var res = hours ? (hours + ':' + ('0' + minutes).slice(-2) + ':' + seconds) : (minutes + ':' + seconds);
        if (days) {
            res = days + '.' + res;
        }
        return (isNegative ? ('-' + res) : res);
    }

//imitating the server side (.net, C#) duration formatting like:

    public static string Format(this TimeSpan interval)
    {
        string pattern;
        if (interval.Days > 0)          pattern = @"d\.h\:mm\:ss";
        else if (interval.Hours > 0)    pattern = @"h\:mm\:ss";
        else                            pattern = @"m\:ss";
        return string.Format("{0}", interval.ToString(pattern));
    }
Winchester answered 28/3, 2015 at 13:27 Comment(0)
A
1
/**
 * Formats seconds (number) to H:i:s format.
 * 00:12:00
 *
 * When "short" option is set to true, will return:
 * 0:50
 * 2:00
 * 12:00
 * 1:00:24
 * 10:00:00
 */
export default function formatTimeHIS (seconds, { short = false } = {}) {
  const pad = num => num < 10 ? `0${num}` : num

  const H = pad(Math.floor(seconds / 3600))
  const i = pad(Math.floor(seconds % 3600 / 60))
  const s = pad(seconds % 60)

  if (short) {
    let result = ''
    if (H > 0) result += `${+H}:`
    result += `${H > 0 ? i : +i}:${s}`
    return result
  } else {
    return `${H}:${i}:${s}`
  }
}
Ashore answered 19/3, 2018 at 13:35 Comment(0)
S
1
secToHHMM(number: number) {
    debugger;
    let hours = Math.floor(number / 3600);
    let minutes = Math.floor((number - (hours * 3600)) / 60);
    let seconds = number - (hours * 3600) - (minutes * 60);
    let H, M, S;
    if (hours < 10) H = ("0" + hours);
    if (minutes < 10) M = ("0" + minutes);
    if (seconds < 10) S = ("0" + seconds);
    return (H || hours) + ':' + (M || minutes) + ':' + (S || seconds);
}
Saddleback answered 19/3, 2018 at 15:37 Comment(0)
M
0

I'd upvote artem's answer, but I am a new poster. I did expand on his solution, though not what the OP asked for as follows

    t=(new Date()).toString().split(" ");
    timestring = (t[2]+t[1]+' <b>'+t[4]+'</b> '+t[6][1]+t[7][0]+t[8][0]);

To get

04Oct 16:31:28 PDT

This works for me...

But if you are starting with just a time quantity, I use two functions; one to format and pad, and one to calculate:

function sec2hms(timect){

  if(timect=== undefined||timect==0||timect === null){return ''};
  //timect is seconds, NOT milliseconds
  var se=timect % 60; //the remainder after div by 60
  timect = Math.floor(timect/60);
  var mi=timect % 60; //the remainder after div by 60
  timect = Math.floor(timect/60);
  var hr = timect % 24; //the remainder after div by 24
  var dy = Math.floor(timect/24);
  return padify (se, mi, hr, dy);
}

function padify (se, mi, hr, dy){
  hr = hr<10?"0"+hr:hr;
  mi = mi<10?"0"+mi:mi;
  se = se<10?"0"+se:se;
  dy = dy>0?dy+"d ":"";
  return dy+hr+":"+mi+":"+se;
}
Mortgagee answered 4/10, 2013 at 23:32 Comment(0)
S
0

If you know the number of seconds you have, this will work. It also uses the native Date() object.

function formattime(numberofseconds){    
    var zero = '0', hours, minutes, seconds, time;

    time = new Date(0, 0, 0, 0, 0, numberofseconds, 0);

    hh = time.getHours();
    mm = time.getMinutes();
    ss = time.getSeconds() 

    // Pad zero values to 00
    hh = (zero+hh).slice(-2);
    mm = (zero+mm).slice(-2);
    ss = (zero+ss).slice(-2);

    time = hh + ':' + mm + ':' + ss;
    return time; 
}
Scourge answered 12/10, 2013 at 21:13 Comment(0)
S
0

Milliseconds to duration, the simple way:

// To have leading zero digits in strings.
function pad(num, size) {
    var s = num + "";
    while (s.length < size) s = "0" + s;
    return s;
}

// ms to time/duration
msToDuration = function(ms){
    var seconds = ms / 1000;
    var hh = Math.floor(seconds / 3600),
    mm = Math.floor(seconds / 60) % 60,
    ss = Math.floor(seconds) % 60,
    mss = ms % 1000;
    return pad(hh,2)+':'+pad(mm,2)+':'+pad(ss,2)+'.'+pad(mss,3);
}

It converts 327577 to 00:05:27.577.

UPDATE

Another way for different scenario:

toHHMMSS = function (n) {
    var sep = ':',
        n = parseFloat(n),
        sss = parseInt((n % 1)*1000),
        hh = parseInt(n / 3600);
    n %= 3600;
    var mm = parseInt(n / 60),
        ss = parseInt(n % 60);
    return pad(hh,2)+sep+pad(mm,2)+sep+pad(ss,2)+'.'+pad(sss,3);
    function pad(num, size) {
        var str = num + "";
        while (str.length < size) str = "0" + str;
        return str;
    }
}

toHHMMSS(6315.077) // Return 01:45:15.077
Scintilla answered 25/8, 2014 at 2:36 Comment(0)
A
0

Non-prototype version of toHHMMSS:

    function toHHMMSS(seconds) {
        var sec_num = parseInt(seconds);
        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;}
        var time    = hours+':'+minutes+':'+seconds;
        return time;
    }   
Amido answered 28/10, 2014 at 16:45 Comment(0)
K
0

Here is my vision of solution. You can try my snippet below.

function secToHHMM(sec) {
  var d = new Date();
  d.setHours(0);
  d.setMinutes(0);
  d.setSeconds(0);
  d = new Date(d.getTime() + sec*1000);
  return d.toLocaleString('en-GB').split(' ')[1];
};

alert( 'One hour: ' + secToHHMM(60*60) ); // '01:00:00'
alert( 'One hour five minutes: ' + secToHHMM(60*60 + 5*60) ); // '01:05:00'
alert( 'One hour five minutes 23 seconds: ' + secToHHMM(60*60 + 5*60 + 23) ); // '01:05:23'
Kaete answered 7/8, 2015 at 16:42 Comment(0)
G
0

This version of the accepted answer makes it a bit prettier if you are dealing with video lengths for example:

1:37:40 (1 hour / 37 minutes / 40 seconds)

1:00 (1 minute)

2:20 (2 minutes and 20 seconds)

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);

  var hourSeparator = ':';
  var minuteSeparator = ':';

  if(hours == 0){hours = '';hourSeparator = '';}
  if (minutes < 10 && hours != 0) {minutes = "0"+minutes;}
  if (seconds < 10) {seconds = "0"+seconds;}
  var time = hours+hourSeparator+minutes+minuteSeparator+seconds;
  return time;
}
Georgie answered 28/8, 2015 at 21:37 Comment(0)
T
0
            //secondsToTime();
            var t = wachttijd_sec; // your seconds
            var hour = Math.floor(t/3600);
            if(hour < 10){
                hour = '0'+hour;
            }
            var time = hour+':'+('0'+Math.floor(t/60)%60).slice(-2)+':'+('0' + t % 60).slice(-2);
            //would output: 00:00:00 > +100:00:00

keeps counten down even if more then 24 hours

Telescopium answered 29/11, 2016 at 15:24 Comment(2)
Kind of you. Not really providing anything substantial that hasn’t been given in one or more of the 30 answers already.Joanejoanie
indeed, juist a trying to help to keep it simpleTelescopium
C
0

You can use Momement.js with moment-duration-format plugin:

var seconds = 3820;
var duration = moment.duration(seconds, 'seconds');
var formatted = duration.format("hh:mm:ss");
console.log(formatted); // 01:03:40
<!-- Moment.js library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

<!-- moment-duration-format plugin -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/1.3.0/moment-duration-format.min.js"></script>

See also this Fiddle

Connect answered 9/5, 2017 at 9:42 Comment(1)
Works like a charm (except format that is not defined) to convert a duration in an object with months, days, hours, minutes and secondsBramblett
O
0
function secondsToTime(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);

    if(hours >= 12)
    {
     var m= 'pm' ;
     }
     else
     {
         var m='am'
     }
     if(hours-12 >0)
     {
            var hrs = hours-12;
     }
     else if(hours-12 <0)
     {
            var hrs = hours;
     }
    var obj = {
        "h": hrs,
        "m": minutes,
        "s": seconds,
        "a":m
    };


    return obj;
}
var d = new Date();
var n = d.getHours();
var hms = d.getHours()+':'+d.getMinutes()+':'+d.getSeconds();   // your input string
var a = hms.split(':'); // split it at the colons

// minutes are worth 60 seconds. Hours are worth 60 minutes.
var seconds = (+a[0]) * 60 * 60 + (+a[1]) * 60 + (+a[2]); 




console.log(seconds);
console.log(secondsToTime(seconds))

https://jsfiddle.net/jithinksoft/9x6z4sdt/

Obtund answered 25/6, 2017 at 6:6 Comment(0)
W
0

Here is an es6 Version of it:

export const parseTime = (time) => { // send time in seconds
// eslint-disable-next-line 
let hours = parseInt(time / 60 / 60), mins = Math.abs(parseInt(time / 60) - (hours * 60)), seconds = Math.round(time % 60);
return isNaN(hours) || isNaN(mins) || isNaN(seconds) ? `00:00:00` : `${hours > 9 ? Math.max(hours, 0) : '0' + Math.max(hours, 0)}:${mins > 9 ? Math.max(mins, 0) : '0' + Math.max(0, mins)}:${seconds > 9 ? Math.max(0, seconds) : '0' + Math.max(0, seconds)}`;}
Wordless answered 29/11, 2018 at 11:14 Comment(0)
B
0

I saw that everybody's posting their takes on the problem despite the fact that few top answers already include all the necessary info to tailor for the specific use case.

And since I want to be hip as well - here's my unnecessary and a bit cumbersome solution, which is:

a) Readable (I hope!)
b) Easily customizable
c) Doesn't print any zeroes

drum roll

function durationToDDHHMMSSMS(durms) {
    if (!durms) return "??";

    var HHMMSSMS = new Date(durms).toISOString().substr(11, 12);
    if (!HHMMSSMS) return "??";

    var HHMMSS = HHMMSSMS.split(".")[0];
    if (!HHMMSS) return "??";

    var MS = parseInt(HHMMSSMS.split(".")[1],10);
    var split = HHMMSS.split(":");
    var SS = parseInt(split[2],10);
    var MM = parseInt(split[1],10);
    var HH = parseInt(split[0],10); 
    var DD = Math.floor(durms/(1000*60*60*24));

    var string = "";
    if (DD) string += ` ${DD}d`;
    if (HH) string += ` ${HH}h`;
    if (MM) string += ` ${MM}m`;
    if (SS) string += ` ${SS}s`;
    if (MS) string += ` ${MS}ms`;

    return string;
},

Note that this code uses ES6 template strings, I'm sure that such a smarty-pants as you are will have no difficulties replacing them with regular strings if required.

Bug answered 31/10, 2019 at 14:59 Comment(0)
T
0

Here's a variation of @meiyang's excellent solution that I ended up using:

    function duration(seconds) {
        return [
            format(seconds / 60 / 60),
            format(seconds / 60 % 60),
            format(seconds % 60)
        ].join(':');
    }

    format(n) {
        return (~~n).toString().padStart(2, '0')
    }

PS: It's also worth noting that some of the other solutions above only work for values < 24h

Tallage answered 2/1, 2023 at 17:20 Comment(0)
A
0

I think this function will do the trick:

const isoToDate = (
  iso: string,
  options?: Intl.DateTimeFormatOptions
) => {
  const date = new Date(iso)

  const time = date.toLocaleTimeString(
    [],
    options || {
      hour: "2-digit",
      minute: "2-digit",
      second: '2-digit'
    }
  )

  return time
}
Astigmatic answered 26/12, 2023 at 11:19 Comment(0)
H
-1

Here's a one-liner updated for 2019:

//your date
var someDate = new Date("Wed Jun 26 2019 09:38:02 GMT+0100") 

var result = `${String(someDate.getHours()).padStart(2,"0")}:${String(someDate.getMinutes()).padStart(2,"0")}:${String(someDate.getSeconds()).padStart(2,"0")}`

//result will be "09:38:02"
Howlyn answered 26/6, 2019 at 15:46 Comment(2)
I think the OP wants to convert a duration (seconds) not a Date object.Photodrama
oops, my bad :(Howlyn
O
-2

I dislike adding properties to standard datatypes in JavaScript, so I would recommend something like this:

/**
 * Format a duration in seconds to a human readable format using the notion
 * "h+:mm:ss", e.g. "4:40:78". Negative durations are preceeded by "-".
 *
 * @param t Duration in seconds
 * @return The formatted duration string
 */
var readableDuration = (function() {

    // Each unit is an object with a suffix s and divisor d
    var units = [
        {s: '', d: 1}, // Seconds
        {s: ':', d: 60}, // Minutes
        {s: ':', d: 60}, // Hours
    ];

    // Closure function
    return function(t) {
        t = parseInt(t); // In order to use modulus
        var trunc, n = Math.abs(t), i, out = []; // out: list of strings to concat
        for (i = 0; i < units.length; i++) {
            n = Math.floor(n / units[i].d); // Total number of this unit
            // Truncate e.g. 26h to 2h using modulus with next unit divisor
            if (i+1 < units.length) // Tweak substr with two digits
                trunc = ('00'+ n % units[i+1].d).substr(-2, 2); // …if not final unit
            else
                trunc = n;
            out.unshift(''+ trunc + units[i].s); // Output
        }
        (t < 0) ? out.unshift('-') : null; // Handle negative durations
        return out.join('');
    };
})();

Usage:

var str = readableDuration(3808); // "1:03:28"

I also created a more generally usable version. The main difference is that it accepts milliseconds (which is kind of the standard time unit in JS) and the output format uses spaces instead.

Olwena answered 22/8, 2013 at 12:26 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.