Convert timestamp to hh:mm:ss javascript

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

UnitDivisions
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]

How to convert time to hh mm ss in javascript?

To convert seconds to HH:MM:SS : Multiply the seconds by 1000 to get milliseconds. Pass the milliseconds to the Date() constructor. Use the toISOString() method on the Date object. Get the hh:mm:ss portion of the string.

How to convert seconds to time in js?

javascript convert seconds to minutes seconds.
function convertHMS(value) {.
const sec = parseInt(value, 10); // convert value to number if it's string..
let hours = Math. ... .
let minutes = Math. ... .
let seconds = sec - (hours * 3600) - (minutes * 60); // get seconds..
// add 0 if value < 10; Example: 2 => 02..

How do you convert seconds to HH mm SS in SQL?

SELECT CONVERT(varchar, DATEADD(ms, 121.25 * 1000, 0), 114) is it. ... .
This won't work if you have more than 24 hours worth of seconds. ... .
Very neat. ... .
If you have SQL 2008+ and just want the time portion; instead of converting to varchar: SELECT CONVERT(time, DATEADD(ms, 121.25 * 1000, 0)) ... .
You can also do FORMAT(..., 'mm:ss').

How do you convert seconds to HH mm SS format in Excel?

As with Excel, the first step to converting elapsed second to time is to divide the value by 86400. To format the cells for mm:ss, select Format > Number > More Formats > More date and time formats from the Menu.