Convert seconds to HH-MM-SS with JavaScript?
Asked Answered
C

37

405

How can I convert seconds to an HH-MM-SS string using JavaScript?

Comprise answered 24/8, 2009 at 14:26 Comment(1)
T
378

Updated (2020):

Please use @Frank's one line solution:

new Date(SECONDS * 1000).toISOString().substring(11, 16)

If SECONDS<3600 and if you want to show only MM:SS then use below code:

new Date(SECONDS * 1000).toISOString().substring(14, 19)

It is by far the best solution.


Old answer:

Use the Moment.js library.

Tenebrae answered 24/8, 2009 at 14:33 Comment(12)
@J.J. Crowder, you are right. But this answer was given on 2009, that time it was a good ideia. I updated my answer.Tenebrae
@Cleiton, your updated answer is not full. I tried it as is and got: TypeError: Object [object Date] has no method 'clearTime'.Sampson
Granted Moment.js isn't all that big but if all you're doing with it is to convert seconds to hh:mm:ss, it seems like a bit of overkill. Rather use one of the functions suggested in these or other answers.Koal
This answer is, if anything, partially wrong. What happens if the amount exceeds 86400 seconds? ;)Malia
I think the other solution is better than throwing another js library in the mix.Zymogen
Adding library for one simple action i think shouldn't be accepted answer. Yes, this works, but there is better solutions!!!Gunnysack
Using this library for one minor task like this adds 59,024 bytes to your project for the same effect that about 53 bytes will give you. . . From below: new Date(SECONDS * 1000).toISOString().substr(11, 8);Tyika
great, but based on requirements if you need it or notGranny
From mozilla: "The toISOString() method returns a string in simplified extended ISO format (ISO 8601), which is always 24 or 27 characters long (YYYY-MM-DDTHH:mm:ss.sssZ or ±YYYYYY-MM-DDTHH:mm:ss.sssZ, respectively)."Indemnification
As long as your number of hours doesn't go over... 24?Strobel
This is plain wrong! As others have pointed put if you have more than a day's worth of secods the answer is incorrect. USE WITH CAUTION! See Santiago Hernández's answer below.Yeta
substr has been deprecated. Answer should probably be updated to use substring instead.Spickandspan
S
574

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

const date = new Date(null);
date.setSeconds(SECONDS); // specify value for SECONDS here
const result = date.toISOString().slice(11, 19);

Or, as per @Frank's comment; a one liner:

new Date(SECONDS * 1000).toISOString().slice(11, 19);
Snook answered 13/8, 2014 at 6:22 Comment(14)
I don't know why everyone is adding extra libraries or doing the math manually when this works perfectly. Thanks!Devan
This can even be shortened to one line: new Date(SECONDS * 1000).toISOString().substr(11, 8);Anglim
The problem with this approach is that it will overflow after 24 hours, preventing you from showing more than this length of time. Perfect solution if you have less than 24 hours in seconds.Dictograph
This does not work for me in IE11, I get Object doesn't support property or method 'toISOString'Amply
As @renatoargh has stated, this solution can only be used for seconds less equal 24 hours, be careful otherwise.Podite
This needs example input & example output.Plio
although this is working, I keep getting the following error: ERROR RangeError: Invalid time value at Date.toISOStringHopple
If you modulus the seconds using the number of seconds in a day, this works for times >= 1 day. new Date(printTime % (60 * 60 * 24)) * 1000).toISOString().substr(11, 8).Deform
for MM:SS -> ...substr(14, 5). I do this after checking if SECONDS < 3600Aretino
I found this on the MDN docs and thought it might be helpful. let [hour, minute, second] = new Date().toLocaleTimeString("en-US").split(/:| /)Auliffe
It is fine to do "new Date" every second? (considering I´m printing a clock) or is it better to reuse date variable and just change seconds every time?Twibill
Nowadays, String.substr() is deprecated. Use String.slice() or String.substring instead.Pooi
But this doesn't display the seconds. Just the hours and minitues :/Accident
substr is deprecated. Use substring(11, 19) or substring(14,19) insteadSwellfish
T
378

Updated (2020):

Please use @Frank's one line solution:

new Date(SECONDS * 1000).toISOString().substring(11, 16)

If SECONDS<3600 and if you want to show only MM:SS then use below code:

new Date(SECONDS * 1000).toISOString().substring(14, 19)

It is by far the best solution.


Old answer:

Use the Moment.js library.

Tenebrae answered 24/8, 2009 at 14:33 Comment(12)
@J.J. Crowder, you are right. But this answer was given on 2009, that time it was a good ideia. I updated my answer.Tenebrae
@Cleiton, your updated answer is not full. I tried it as is and got: TypeError: Object [object Date] has no method 'clearTime'.Sampson
Granted Moment.js isn't all that big but if all you're doing with it is to convert seconds to hh:mm:ss, it seems like a bit of overkill. Rather use one of the functions suggested in these or other answers.Koal
This answer is, if anything, partially wrong. What happens if the amount exceeds 86400 seconds? ;)Malia
I think the other solution is better than throwing another js library in the mix.Zymogen
Adding library for one simple action i think shouldn't be accepted answer. Yes, this works, but there is better solutions!!!Gunnysack
Using this library for one minor task like this adds 59,024 bytes to your project for the same effect that about 53 bytes will give you. . . From below: new Date(SECONDS * 1000).toISOString().substr(11, 8);Tyika
great, but based on requirements if you need it or notGranny
From mozilla: "The toISOString() method returns a string in simplified extended ISO format (ISO 8601), which is always 24 or 27 characters long (YYYY-MM-DDTHH:mm:ss.sssZ or ±YYYYYY-MM-DDTHH:mm:ss.sssZ, respectively)."Indemnification
As long as your number of hours doesn't go over... 24?Strobel
This is plain wrong! As others have pointed put if you have more than a day's worth of secods the answer is incorrect. USE WITH CAUTION! See Santiago Hernández's answer below.Yeta
substr has been deprecated. Answer should probably be updated to use substring instead.Spickandspan
A
216

I don't think any built-in feature of the standard Date object will do this for you in a way that's more convenient than just doing the math yourself.

hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
minutes = Math.floor(totalSeconds / 60);
seconds = totalSeconds % 60;

Example:

let totalSeconds = 28565;
let hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
let minutes = Math.floor(totalSeconds / 60);
let seconds = totalSeconds % 60;

console.log("hours: " + hours);
console.log("minutes: " + minutes);
console.log("seconds: " + seconds);

// If you want strings with leading zeroes:
minutes = String(minutes).padStart(2, "0");
hours = String(hours).padStart(2, "0");
seconds = String(seconds).padStart(2, "0");
console.log(hours + ":" + minutes + ":" + seconds);
Astrea answered 24/8, 2009 at 14:39 Comment(4)
This is the most correct answer because it doesn't overflow if more than 24 hours.Crockery
Edge case perhaps, yet something to be aware of: suppose a value such as totalSeconds = 1739.8395. (T.J. mentions fractional portions in comment above.) Formula computes "seconds" as 59.839500000000044. If a person wants to round up, then 59 seconds becomes 60 seconds. Meaning, "seconds" value needs to be set to 0, and 1 minute needs to be added to "minutes". And if "minutes" value happened to be 59, "minutes" value becomes 60, and so "minutes" needs to be reset to 0, and 1 hour needs to be added to "hours".Hurlyburly
@Hurlyburly - The simplest solution there would be to start out with totalSeconds = Math.round(totalSeconds);. :-)Astrea
related: https://mcmap.net/q/35709/-how-to-perform-an-integer-division-and-separately-get-the-remainder-in-javascriptIndemnification
R
139

I know this is kinda old, but...

ES2015:

var toHHMMSS = (secs) => {
    var sec_num = parseInt(secs, 10)
    var hours   = Math.floor(sec_num / 3600)
    var minutes = Math.floor(sec_num / 60) % 60
    var seconds = sec_num % 60

    return [hours,minutes,seconds]
        .map(v => v < 10 ? "0" + v : v)
        .filter((v,i) => v !== "00" || i > 0)
        .join(":")
}

It will output:

toHHMMSS(129600) // 36:00:00
toHHMMSS(13545) // 03:45:45
toHHMMSS(180) // 03:00
toHHMMSS(18) // 00:18
Rawlinson answered 17/1, 2016 at 17:4 Comment(1)
What about fractions of a second? 03:45:45.xxx?Polypeptide
H
44

As Cleiton pointed out in his answer, moment.js can be used for this:

moment().startOf('day')
        .seconds(15457)
        .format('H:mm:ss');
Hickerson answered 18/10, 2013 at 19:30 Comment(5)
What happens if the number of seconds exceeds a day?Belvia
@GiladPeleg if the number of seconds exceeds a day, number of days is calculated internally and it will only return the remaining hours, minutes and seconds. If you want to count number of days as well, you can try moment().startOf('year').seconds(30000000).format('DDD HH:mm:ss').Ingathering
What happens if the number of seconds exceeds a year?Allpurpose
@Allpurpose if the number of seconds exceeds a year, number of years is calculated internally and it will only return the remaining days, hours, minutes and seconds. If you want to count number of years as well, you can try .format('YYYY DDD HH:mm:ss')Squirrel
But this cannot be made optional. That might look ugly.Belinda
J
26

Here's a simple function for converting times that might help

function formatSeconds(seconds) {
    var date = new Date(1970,0,1);
    date.setSeconds(seconds);
    return date.toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");
}
Jabot answered 22/7, 2013 at 6:14 Comment(2)
formatSeconds(3919); //Returns 01:05:19 Excellent Function .. Like itSubscription
Like said before, this will overflow after 24 hoursVashtivashtia
M
19

This does the trick:

function secondstotime(secs)
{
    var t = new Date(1970,0,1);
    t.setSeconds(secs);
    var s = t.toTimeString().substr(0,8);
    if(secs > 86399)
        s = Math.floor((t - Date.parse("1/1/70")) / 3600000) + s.substr(2);
    return s;
}

(Sourced from here)

Myth answered 24/8, 2009 at 14:42 Comment(0)
S
15
var  timeInSec = "661"; //even it can be string

String.prototype.toHHMMSS = function () { 
   /* extend the String by using prototypical inheritance */
    var seconds = parseInt(this, 10); // don't forget the second param
    var hours   = Math.floor(seconds / 3600);
    var minutes = Math.floor((seconds - (hours * 3600)) / 60);
    seconds = seconds - (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;
}

alert("5678".toHHMMSS());   // "01:34:38"
console.log(timeInSec.toHHMMSS());   //"00:11:01"

we can make this function lot shorter and crisp but that decreases the readability, so we will write it as simple as possible and as stable as possible.

or you can check this working here:

Stoplight answered 30/1, 2014 at 12:5 Comment(2)
moreover ... if u want to do all date time thing easily.. use momentJSStoplight
Thanks! no need to include a Library in a browser extension. Simple and works!Substratum
P
12

I think the most general (and cryptic) solution could be this

function hms(seconds) {
  return [3600, 60]
    .reduceRight(
      (pipeline, breakpoint) => remainder =>
        [Math.floor(remainder / breakpoint)].concat(pipeline(remainder % breakpoint)),
      r => [r]
    )(seconds)
    .map(amount => amount.toString().padStart(2, '0'))
    .join('-');
}

Or to copy & paste the shortest version

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"

How it works

Algorithm

  1. To get hours you divide total seconds by 3600 and floor it.
  2. To get minutes you divide remainder by 60 and floor it.
  3. To get seconds you just use the remainder.

It would also be nice to keep individual amounts in an array for easier formatting.

For example given the input of 3785s the output should be [1, 3, 5], that is 1 hour, 3 minutes and 5 seconds.

Creating pipeline

Naming the 3600 and 60 constants "breakpoints" you can write this algorithm into function as this

function divideAndAppend(remainder, breakpoint, callback) {
  return [Math.floor(remainder / breakpoint)].concat(callback(remainder % breakpoint));
}

It returns an array where first item is the amount for given breakpoint and the rest of the array is given by the callback. Reusing the divideAndAppend in callback function will give you a pipeline of composed divideAndAppend functions. Each one of these computes amount per given breakpoint and append it to the array making your desired output.

Then you also need the "final" callback that ends this pipeline. In another words you used all breakpoints and now you have only the remainder. Since you have already the answer at 3) you should use some sort of identity function, in this case remainder => [remainder].

You can now write the pipeline like this

let pipeline = r3 => divideAndAppend(
    r3, 
    3600, 
    r2 => divideAndAppend(
        r2, 
        60, 
        r1 => [r1]));

> pipeline(3785)
< [1, 3, 5]

Cool right?

Generalizing using for-loop

Now you can generalize with a variable amount of breakpoints and create a for-loop that will compose individial divideAndAppend functions into the pipeline. You start with the identity function r1 => [r1], then use the 60 breakpoint and finally use the 3600 breakpoint.

let breakpoints = [60, 3600];
let pipeline = r => [r];

for (const b of breakpoints) {
  const previousPipeline = pipeline;
  pipeline = r => divideAndAppend(r, b, previousPipeline);
}

> pipeline(3785)
< [1, 3, 5]

Using Array.prototype.reduce()

Now you can rewrite this for-loop into reducer for shorter and more functional code. In other words rewrite function composition into the reducer.

let pipeline = [60, 3600].reduce(
  (ppln, b) => r => divideAndAppend(r, b, ppln),
  r => [r]
);

> pipeline(3785)
< [1, 3, 5]

The accumulator ppln is the pipeline and you are composing it using the previous version of it. The initial pipeline is r => [r].

You can now inline the function divideAndAppend and use Array.prototype.reduceRight which is the same as [].reverse().reduce(...) to make the breakpoints definitions more natural.

let pipeline = [3600, 60]
    .reduceRight(
      (ppln, b) => r => [Math.floor(r / b)].concat(ppln(r % b)),
      r => [r]
    );

Which is the final form. Then you just appy mapping to string with padded 0's on left and join the strings with : separator;

More generalizations

Wrapping the reducer into function

function decompose(total, breakpoints) {
  return breakpoints.reduceRight(
    (p, b) => r => [Math.floor(r / b)].concat(p(r % b)),
    r => [r]
  )(total);
}

> decompose(3785, [3600, 60])
< [1, 3, 5]

you now have very general algorithm you can work with. For example:

Convert easily (the weird) us length standards

Given the standards

Unit Divisions
1 foot 12 inches
1 yard 3 feet
1 mile 1760 yards
> decompose(123_456, [1760 * 3 * 12, 3 * 12, 12])
< [1, 1669, 1, 0]

123456 in = 1 mi, 1669 yd, 1 feet and 0 in

Or you can somewhat convert to decimal or binary representations

> decompose(123_456, [100_000, 10_000, 1000, 100, 10])
< [1, 2, 3, 4, 5, 6]

> decompose(127, [128, 64, 32, 16, 8, 4, 2])
< [0, 1, 1, 1, 1, 1, 1, 1]

Works also with floating point breakpoints

Since Javascript supports mod operator with floating point numbers, you can also do

> decompose(26.5, [20, 2.5])
< [1, 2, 1.5]

The edge case of no breakpoints is also naturally covered

> decompose(123, [])
< [123]
Posterior answered 6/3, 2021 at 11:0 Comment(0)
S
10

Try this:

function toTimeString(seconds) {
  return (new Date(seconds * 1000)).toUTCString().match(/(\d\d:\d\d:\d\d)/)[0];
}
Scuffle answered 14/4, 2015 at 3:29 Comment(0)
G
9

Here is an extension to Number class. toHHMMSS() converts seconds to an hh:mm:ss string.

Number.prototype.toHHMMSS = function() {
  var hours = Math.floor(this / 3600) < 10 ? ("00" + Math.floor(this / 3600)).slice(-2) : Math.floor(this / 3600);
  var minutes = ("00" + Math.floor((this % 3600) / 60)).slice(-2);
  var seconds = ("00" + (this % 3600) % 60).slice(-2);
  return hours + ":" + minutes + ":" + seconds;
}

// Usage: [number variable].toHHMMSS();

// Here is a simple test
var totalseconds = 1234;
document.getElementById("timespan").innerHTML = totalseconds.toHHMMSS();
// HTML of the test
<div id="timespan"></div>
Germanium answered 29/6, 2015 at 9:51 Comment(0)
G
5

Easy to follow version for noobies:

 var totalNumberOfSeconds = YOURNUMBEROFSECONDS;
 var hours = parseInt( totalNumberOfSeconds / 3600 );
 var minutes = parseInt( (totalNumberOfSeconds - (hours * 3600)) / 60 );
 var seconds = Math.floor((totalNumberOfSeconds - ((hours * 3600) + (minutes * 60))));
 var result = (hours < 10 ? "0" + hours : hours) + ":" + (minutes < 10 ? "0" + minutes : minutes) + ":" + (seconds  < 10 ? "0" + seconds : seconds);
 console.log(result);
Gesture answered 24/2, 2015 at 7:8 Comment(0)
D
5

This function should do it :

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

See also this Fiddle.

Dagall answered 7/2, 2017 at 14:1 Comment(2)
Could use default parameters like (input ,separator=":"). Also it didn't return anything until I modified it a bit paste.ee/p/FDNagCapsaicin
@Capsaicin : Actually, the version in my answer already sets : as default for the separator parameter, as I already explained. This is done by the statement typeof separator !== 'undefined' ? separator : ':'. Also, your function is pretty much identical to mine save some cosmetic changes and they should both produce the same output... except my version has much better browser support. Yours won't work in ANY version of Internet Explorer or MS Edge < 14.Dagall
I
5

Chiming in on this old thread -- the OP stated HH:MM:SS, and many of the solutions work, until you realize you need more than 24 hours listed. And maybe you don't want more than a single line of code. Here you go:

d=(s)=>{f=Math.floor;g=(n)=>('00'+n).slice(-2);return f(s/3600)+':'+g(f(s/60)%60)+':'+g(s%60)}

It returns H+:MM:SS. To use it, simply use:

d(91260);     // returns "25:21:00"
d(960);       // returns "0:16:00"

...I tried to get it to use the least amount of code possible, for a nice one-liner approach.

Incapable answered 30/6, 2017 at 1:58 Comment(1)
Can you provide an expanded/reading version of your code as well so we can more easily see what is happening? Thanks.Quitrent
E
5

For the special case of HH:MM:SS.MS (eq: "00:04:33.637") as used by FFMPEG to specify milliseconds.

[-][HH:]MM:SS[.m...]

HH expresses the number of hours, MM the number of minutes for a maximum of 2 digits, and SS the number of seconds for a maximum of 2 digits. The m at the end expresses decimal value for SS.

/* HH:MM:SS.MS to (FLOAT)seconds ---------------*/
function timerToSec(timer){
   let vtimer = timer.split(":")
   let vhours = +vtimer[0]
   let vminutes = +vtimer[1]
   let vseconds = parseFloat(vtimer[2])
   return vhours * 3600 + vminutes * 60 + vseconds
}

/* Seconds to (STRING)HH:MM:SS.MS --------------*/
function secToTimer(sec){
  let o = new Date(0)
  let p =  new Date(sec*1000)  
  return new Date(p.getTime()-o.getTime())
    .toISOString()
    .split("T")[1]
    .split("Z")[0]
}

/* Example: 7hours, 4 minutes, 33 seconds and 637 milliseconds */
const t = "07:04:33.637"
console.log(
  t + " => " +
  timerToSec(t) +
  "s"
)

/* Test: 25473 seconds and 637 milliseconds */
const s = 25473.637 // "25473.637"
console.log(
  s + "s => " + 
  secToTimer(s)
)

Example usage, a milliseconds transport timer:

/* Seconds to (STRING)HH:MM:SS.MS --------------*/
function secToTimer(sec){
  let o = new Date(0)
  let p =  new Date(sec*1000)  
  return new Date(p.getTime()-o.getTime())
    .toISOString()
    .split("T")[1]
    .split("Z")[0]
}

let job, origin = new Date().getTime()
const timer = () => {
  job = requestAnimationFrame(timer)
  OUT.textContent = secToTimer((new Date().getTime() - origin) / 1000)
}

requestAnimationFrame(timer)
span {font-size:4rem}
<span id="OUT"></span>
<br>
<button onclick="origin = new Date().getTime()">RESET</button>
<button onclick="requestAnimationFrame(timer)">RESTART</button>
<button onclick="cancelAnimationFrame(job)">STOP</button>

Example usage, binded to a media element

/* Seconds to (STRING)HH:MM:SS.MS --------------*/
function secToTimer(sec){
  let o = new Date(0)
  let p =  new Date(sec*1000)  
  return new Date(p.getTime()-o.getTime())
    .toISOString()
    .split("T")[1]
    .split("Z")[0]
}

VIDEO.addEventListener("timeupdate", function(e){
  OUT.textContent = secToTimer(e.target.currentTime)
}, false)
span {font-size:4rem}
<span id="OUT"></span><br>
<video id="VIDEO" width="400" controls autoplay>
  <source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
</video>

Outside the question, those functions written in php:

<?php 
/* HH:MM:SS to (FLOAT)seconds ------------------*/
function timerToSec($timer){
  $vtimer = explode(":",$timer);
  $vhours = (int)$vtimer[0];
  $vminutes = (int)$vtimer[1];
  $vseconds = (float)$vtimer[2];
  return $vhours * 3600 + $vminutes * 60 + $vseconds;
}
/* Seconds to (STRING)HH:MM:SS -----------------*/
function secToTimer($sec){
  return explode(" ", date("H:i:s", $sec))[0];  
}
Emmery answered 20/8, 2019 at 10:32 Comment(2)
You can omit + "." + p.getMilliseconds() by just using new Date(p.getTime()-o.getTime()).toISOString().split("T")[1].split("Z")[0] Ronn
Looks alright, yes your version it faster: See benchmark jsben.ch/4sQY1 Accepted edit! Thank you.Emmery
G
4

After looking at all the answers and not being happy with most of them, this is what I came up with. I know I am very late to the conversation, but here it is anyway.

function secsToTime(secs){
  var time = new Date(); 
  // create Date object and set to today's date and time
  time.setHours(parseInt(secs/3600) % 24);
  time.setMinutes(parseInt(secs/60) % 60);
  time.setSeconds(parseInt(secs%60));
  time = time.toTimeString().split(" ")[0];
  // time.toString() = "HH:mm:ss GMT-0800 (PST)"
  // time.toString().split(" ") = ["HH:mm:ss", "GMT-0800", "(PST)"]
  // time.toTimeString().split(" ")[0]; = "HH:mm:ss"
  return time;
}

I create a new Date object, change the time to my parameters, convert the Date Object to a time string, and removed the additional stuff by splitting the string and returning only the part that need.

I thought I would share this approach, since it removes the need for regex, logic and math acrobatics to get the results in "HH:mm:ss" format, and instead it relies on built in methods.

You may want to take a look at the documentation here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

Guanase answered 15/1, 2016 at 20:29 Comment(0)
S
4

below is the given code which will convert seconds into hh-mm-ss format:

var measuredTime = new Date(null);
measuredTime.setSeconds(4995); // specify value of SECONDS
var MHSTime = measuredTime.toISOString().substr(11, 8);

Get alternative method from Convert seconds to HH-MM-SS format in JavaScript

Suspicion answered 18/7, 2017 at 21:10 Comment(1)
Did you copy paste from this answer?Harriott
C
4

Simple function to convert seconds into in hh:mm:ss format :

function getHHMMSSFromSeconds(totalSeconds) {
    if (!totalSeconds) {
      return '00:00:00';
    }
    const hours = Math.floor(totalSeconds / 3600);
    const minutes = Math.floor(totalSeconds % 3600 / 60);
    const seconds = totalSeconds % 60;
    const hhmmss = padTo2(hours) + ':' + padTo2(minutes) + ':' + padTo2(seconds);
    return hhmmss;
}

// function to convert single digit to double digit
function padTo2(value) {
    if (!value) {
      return '00';
    }
    return value < 10 ? String(value).padStart(2, '0') : value;
}
Cristacristabel answered 3/6, 2021 at 20:14 Comment(0)
R
3
var time1 = date1.getTime();
var time2 = date2.getTime();
var totalMilisec = time2 - time1;

alert(DateFormat('hh:mm:ss',new Date(totalMilisec)))

 /* ----------------------------------------------------------
 *  Field        | Full Form          | Short Form
 *  -------------|--------------------|-----------------------
 *  Year         | yyyy (4 digits)    | yy (2 digits)
 *  Month        | MMM (abbr.)        | MM (2 digits)
                 | NNN (name)         |
 *  Day of Month | dd (2 digits)      | 
 *  Day of Week  | EE (name)          | E (abbr)
 *  Hour (1-12)  | hh (2 digits)      | 
 *  Minute       | mm (2 digits)      | 
 *  Second       | ss (2 digits)      | 
 *  ----------------------------------------------------------
 */
function DateFormat(formatString,date){
    if (typeof date=='undefined'){
    var DateToFormat=new Date();
    }
    else{
        var DateToFormat=date;
    }
    var DAY         = DateToFormat.getDate();
    var DAYidx      = DateToFormat.getDay();
    var MONTH       = DateToFormat.getMonth()+1;
    var MONTHidx    = DateToFormat.getMonth();
    var YEAR        = DateToFormat.getYear();
    var FULL_YEAR   = DateToFormat.getFullYear();
    var HOUR        = DateToFormat.getHours();
    var MINUTES     = DateToFormat.getMinutes();
    var SECONDS     = DateToFormat.getSeconds();

    var arrMonths = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
    var arrDay=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
    var strMONTH;
    var strDAY;
    var strHOUR;
    var strMINUTES;
    var strSECONDS;
    var Separator;

    if(parseInt(MONTH)< 10 && MONTH.toString().length < 2)
        strMONTH = "0" + MONTH;
    else
        strMONTH=MONTH;
    if(parseInt(DAY)< 10 && DAY.toString().length < 2)
        strDAY = "0" + DAY;
    else
        strDAY=DAY;
    if(parseInt(HOUR)< 10 && HOUR.toString().length < 2)
        strHOUR = "0" + HOUR;
    else
        strHOUR=HOUR;
    if(parseInt(MINUTES)< 10 && MINUTES.toString().length < 2)
        strMINUTES = "0" + MINUTES;
    else
        strMINUTES=MINUTES;
    if(parseInt(SECONDS)< 10 && SECONDS.toString().length < 2)
        strSECONDS = "0" + SECONDS;
    else
        strSECONDS=SECONDS;

    switch (formatString){
        case "hh:mm:ss":
            return strHOUR + ':' + strMINUTES + ':' + strSECONDS;
        break;
        //More cases to meet your requirements.
    }
}
Rub answered 24/5, 2011 at 13:21 Comment(0)
Z
3

I just wanted to give a little explanation to the nice answer above:

var totalSec = new Date().getTime() / 1000;
var hours = parseInt( totalSec / 3600 ) % 24;
var minutes = parseInt( totalSec / 60 ) % 60;
var seconds = totalSec % 60;

var result = (hours < 10 ? "0" + hours : hours) + "-" + (minutes < 10 ? "0" + minutes : minutes) + "-" + (seconds  < 10 ? "0" + seconds : seconds);

On the second line, since there are 3600 seconds in 1 hour, we divide the total number of seconds by 3600 to get the total number of hours. We use parseInt to strip off any decimal. If totalSec was 12600 (3 and half hours), then parseInt( totalSec / 3600 ) would return 3, since we will have 3 full hours. Why do we need the % 24 in this case? If we exceed 24 hours, let's say we have 25 hours (90000 seconds), then the modulo here will take us back to 1 again, rather than returning 25. It is confining the result within a 24 hour limit, since there are 24 hours in one day.

When you see something like this:

25 % 24

Think of it like this:

25 mod 24 or what is the remainder when we divide 25 by 24
Zymogen answered 19/7, 2016 at 20:27 Comment(0)
F
3

None of the answers here satisfies my requirements as I want to be able to handle

  1. Large numbers of seconds (days), and
  2. Negative numbers

Although those are not required by the OP, it's good practice to cover edge cases, especially when it takes little effort.

It's pretty obvious is that the OP means a NUMBER of seconds when he says seconds. Why would peg your function on String?

function secondsToTimeSpan(seconds) {
    const value = Math.abs(seconds);
    const days = Math.floor(value / 1440);
    const hours = Math.floor((value - (days * 1440)) / 3600);
    const min = Math.floor((value - (days * 1440) - (hours * 3600)) / 60);
    const sec = value - (days * 1440) - (hours * 3600) - (min * 60);
    return `${seconds < 0 ? '-':''}${days > 0 ? days + '.':''}${hours < 10 ? '0' + hours:hours}:${min < 10 ? '0' + min:min}:${sec < 10 ? '0' + sec:sec}`
}
secondsToTimeSpan(0);       // => 00:00:00
secondsToTimeSpan(1);       // => 00:00:01
secondsToTimeSpan(1440);    // => 1.00:00:00
secondsToTimeSpan(-1440);   // => -1.00:00:00
secondsToTimeSpan(-1);      // => -00:00:01
Floranceflore answered 29/4, 2019 at 3:46 Comment(1)
secondsToTimeSpan(8991) returns 6.00:05:51 whereas i think it should return 00:02:29:51Tympany
J
3
export const secondsToHHMMSS = (seconds) => {
  const HH = `${Math.floor(seconds / 3600)}`.padStart(2, '0');
  const MM = `${Math.floor(seconds / 60) % 60}`.padStart(2, '0');
  const SS = `${Math.floor(seconds % 60)}`.padStart(2, '0');
  return [HH, MM, SS].join(':');
};
Joell answered 11/11, 2022 at 17:50 Comment(2)
Great solution! This seems to work best for my situation. I will always need HH to show even if its 00: Thank you.Helminthic
Works greatly with 24H+ seconds as well.Atom
D
2

Have you tried adding seconds to a Date object?

Date.prototype.addSeconds = function(seconds) {
    this.setSeconds(this.getSeconds() + seconds);
};
var dt = new Date();
dt.addSeconds(1234);

A sample: https://jsfiddle.net/j5g2p0dc/5/

Updated: Sample link was missing so I created a new one.

Delacourt answered 31/3, 2014 at 14:2 Comment(3)
Uncaught TypeError: dt.addSeconds is not a functionOppen
@Oppen check the sample, I created a new one in jsfiddle since the old one returned 404 errorDelacourt
Looks like I didn't release that you were using custom method addSeconds on Date object like Date.prototype.addSeconds = function(seconds){...}. Yes, it works, thanks for the update.Oppen
L
2

Here is a function to convert seconds to hh-mm-ss format based on powtac's answer here

jsfiddle

/** 
 * Convert seconds to hh-mm-ss format.
 * @param {number} totalSeconds - the total seconds to convert to hh- mm-ss
**/
var SecondsTohhmmss = function(totalSeconds) {
  var hours   = Math.floor(totalSeconds / 3600);
  var minutes = Math.floor((totalSeconds - (hours * 3600)) / 60);
  var seconds = totalSeconds - (hours * 3600) - (minutes * 60);

  // round seconds
  seconds = Math.round(seconds * 100) / 100

  var result = (hours < 10 ? "0" + hours : hours);
      result += "-" + (minutes < 10 ? "0" + minutes : minutes);
      result += "-" + (seconds  < 10 ? "0" + seconds : seconds);
  return result;
}

Example use

var seconds = SecondsTohhmmss(70);
console.log(seconds);
// logs 00-01-10
Leporid answered 27/1, 2015 at 23:25 Comment(0)
R
2

There are lots of options of solve this problem, and obvious there are good option suggested about, But I wants to add one more optimized code here

function formatSeconds(sec) {
     return [(sec / 3600), ((sec % 3600) / 60), ((sec % 3600) % 60)]
            .map(v => v < 10 ? "0" + parseInt(v) : parseInt(v))
            .filter((i, j) => i !== "00" || j > 0)
            .join(":");
}

if you don't wants formatted zero with less then 10 number, you can use

function formatSeconds(sec) {
  return parseInt(sec / 3600) + ':' + parseInt((sec % 3600) / 60) + ':' + parseInt((sec % 3600) % 60);

}

Sample Code http://fiddly.org/1c476/1

Readable answered 5/12, 2017 at 12:54 Comment(0)
B
2

In one line, using T.J. Crowder's solution :

secToHHMMSS = seconds => `${Math.floor(seconds / 3600)}:${Math.floor((seconds % 3600) / 60)}:${Math.floor((seconds % 3600) % 60)}`

In one line, another solution that also count days :

secToDHHMMSS = seconds => `${parseInt(seconds / 86400)}d ${new Date(seconds * 1000).toISOString().substr(11, 8)}`

Source : https://gist.github.com/martinbean/2bf88c446be8048814cf02b2641ba276

Bushman answered 24/4, 2018 at 15:5 Comment(0)
M
2
var sec_to_hms = function(sec){
var min, hours;
     sec = sec - (min = Math.floor(sec/60))*60;
     min = min - (hours = Math.floor(min/60))*60;
     return (hours?hours+':':'') + ((min+'').padStart(2, '0')) + ':'+ ((sec+'').padStart(2, '0'));
}
alert(sec_to_hms(2442542));
Mitchiner answered 10/8, 2018 at 16:52 Comment(0)
P
2

You can use ES6 generator to create highly customizable time strings.

Here is the general function to convert a number to an array from a given scale:

function toScaledArray(n,scales){
  function* g(x, n=0){
    if(x>0) {
      yield x%(scales[n]||Infinity);
      yield* g(Math.floor(x/scales[n]),n+1)
    }
  }
  return [...g(n)]
}

console.log(toScaledArray(6,[10,10]))
console.log(toScaledArray(2000,[30,12]))
console.log(toScaledArray(45000,[24,30,12]))

So, we can use it to create time strings as follows:

> toScaledArray(45000,[60,60]).reverse().join(":")
< '12:30:0'
> toScaledArray(1234,[60,60]).reverse().join(":")
< '20:34'

The function can be also written in one line:

[...(function* g(x,n=0,scales=[60,60]){if(x>0) {yield x%(scales[n]||Infinity); yield* g(Math.floor(x/scales[n]),n+1,scales)}})(45000)].reverse().join("-")

Functions above will omit the leading zeros, if you want to convert a string into precisely 'HH-MM-SS', you can use

[...(function* g(x,n=0,scales=[60,60]){if(x>0||n<3) {yield x%(scales[n]||Infinity); yield* g(Math.floor(x/scales[n]),n+1,scales)}})(45000)].reverse().map(x=>String(x).padStart(2, '0')).join("-")

Also, if what you need is '[H:]MM:SS', here we have:

Number.prototype.toTimeString = function(){
  return [...(function* g(x,n=0,scales=[60,60]){if(x>0||n<2) {yield x%(scales[n]||Infinity); yield* g(Math.floor(x/scales[n]),n+1,scales)}})(this)].map((x,n)=>n<2?String(x).padStart(2,'0'):x).reverse().join(":")
}

console.log(12,(12).toTimeString())
console.log(345,(345).toTimeString())
console.log(6789,(6789).toTimeString())

and you can also have D(ay) or even M(onth) and Y(ear) (not precisely though) as follows:

> toScaledArray(123456789,[60,60,24,30,12]).map((x,n)=>n<2?String(x).padStart(2,'0'):x).reverse().join(":")
< '3:11:18:21:33:09'

Here the output means "3 years 11 months 18 days 21 hours 33 minutes and 9 seconds"

In conclusion, this is a highly customizable way to convert a number into scaled arrays, which can be used in time string conversion, human readable byte conversion or even change for paper money.

Poleax answered 18/9, 2022 at 3:5 Comment(0)
G
1

You can also use below code:

int ss = nDur%60;
nDur   = nDur/60;
int mm = nDur%60;
int hh = nDur/60;
Goaltender answered 13/11, 2012 at 15:11 Comment(0)
V
1

For anyone using AngularJS, a simple solution is to filter the value with the date API, which converts milliseconds to a string based on the requested format. Example:

<div>Offer ends in {{ timeRemaining | date: 'HH:mm:ss' }}</div>

Note that this expects milliseconds, so you may want to multiply timeRemaining by 1000 if you are converting from seconds (as the original question was formulated).

Viosterol answered 15/12, 2014 at 10:28 Comment(0)
K
1

I ran into the case some have mentioned where the number of seconds is more than a day. Here's an adapted version of @Harish Anchu's top-rated answer that accounts for longer periods of time:

function secondsToTime(seconds) {
  const arr = new Date(seconds * 1000).toISOString().substr(11, 8).split(':');

  const days = Math.floor(seconds / 86400);
  arr[0] = parseInt(arr[0], 10) + days * 24;

  return arr.join(':');
}

Example:

secondsToTime(101596) // outputs '28:13:16' as opposed to '04:13:16'
Kosey answered 28/9, 2018 at 20:10 Comment(0)
O
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;
}

// For Example :
alert("186".toHHMMSS());
Orts answered 17/3, 2019 at 15:37 Comment(0)
L
1

Already many answers, but my requirements were:

  • convert to duration (i.e., should work for values larger than 24 hours)
  • care about the decimals of seconds up to given decimal precision
  • truncate the preceding hours and mins if zero.

const seconds2duration = ( seconds, decimals=0 ) => {
    let fraction = ( seconds - Math.floor( seconds ) ).toFixed( decimals );
    fraction = decimals === 0 ? '' : fraction.slice( 1 );
    const [ hours, mins, secs ] = [ seconds / 3600, seconds % 3600 / 60, seconds % 3600 % 60 ].map( ( x ) => String( Math.floor( x ) ).padStart( 2, '0' ) );
    if ( hours === '00' && mins === '00' ) {
        return secs + fraction;
    } else if ( hours === '00' ) {
        return [ mins, secs + fraction ].join( ':' );
    } else {
        return [ hours, mins, secs + fraction ].join( ':' );
    }
};

console.log(seconds2duration(25*3600 + 0*60 + 41 + 0.333, 0)); // 25:00:41
console.log(seconds2duration(0*3600 + 5*60 + 41 + 0.333, 0)); // 05:41
console.log(seconds2duration(0*3600 + 5*60 + 41 + 0.333, 1)); // 05:41.3
console.log(seconds2duration(0*3600 + 0*60 + 41 + 0.333, 2)); // 41.33
Lynnlynna answered 19/8, 2022 at 23:45 Comment(0)
Z
0

When I picture a clock or a timer, I would do it as shown below:

const secondsTo_HHMMSS = (seconds) => {
      //format to a readable friendly timer
      let hour = Math.floor(seconds / 3600);
      let minute = Math.floor((seconds % 3600) / 60);
      let second = seconds % 60;

      if(hour.toString().length === 1) {
            hour = `0${hour}`;
      }
      if(minute.toString().length === 1) {
            minute = `0${minute}`;
      }
      if(second.toString().length === 1) {
            second = `0${second}`;
      };

      let timer = `${hour}-${minute}-${second}`;

      return timer;
}
Zelig answered 18/5, 2022 at 18:34 Comment(0)
S
0

A good option could be to use Intl.DateTimeFormat. Example:

const timeFormat = new Intl.DateTimeFormat('es-US', {
    hour: 'numeric',
    minute: 'numeric',
    second: 'numeric',
    hour12: false,
    timeZone: 'UTC'
});

const endTimeFormatted = timeFormat.format(new Date(SECS * 1000); //hour in secs
Soutine answered 16/9, 2022 at 15:58 Comment(0)
D
-2

You can also use Sugar.

Date.create().reset().set({seconds: 180}).format('{mm}:{ss}');

This example returns '03:00'.

Downwards answered 12/4, 2012 at 8:0 Comment(2)
That sounded good !After checking, it does not returns 03:00, but for any value entered, just 00:00.Breakthrough
They might have changed their API. I've updated the code (it's 2 years too late and you probably moved on, but I thought others might find it useful).Downwards
C
-4

I've used this code before to create a simple timespan object:

function TimeSpan(time) {
this.hours = 0;
this.minutes = 0;
this.seconds = 0;

while(time >= 3600)
{
    this.hours++;
    time -= 3600;
}

while(time >= 60)
{
    this.minutes++;
    time -= 60;
}

this.seconds = time;
}

var timespan = new Timespan(3662);
Clarissaclarisse answered 24/8, 2009 at 14:41 Comment(1)
looping results is a very bad coding technique and should never be used it will hog your processing power and give you a laggy siteMarcum

© 2022 - 2024 — McMap. All rights reserved.