Question

Soundcloud's API gives the duration of it's tracks as milliseconds. JSON looks like this:

"duration": 298999

I've tried many functions I found on here to no avail. I'm just looking for something to convert that number to something like looks like this:

4:59

Here's one that got close, but doesn't work. It doesn't stop the seconds at 60. It goes all the way to 99 which makes no sense. Try entering "187810" as a value of ms, for example.

var ms = 298999,
min = Math.floor((ms/1000/60) << 0),
sec = Math.floor((ms/1000) % 60);

console.log(min + ':' + sec);

Thanks for your help!

If you could add in support for hours, too, I would be grateful.

Was it helpful?

Solution

function millisToMinutesAndSeconds(millis) {
  var minutes = Math.floor(millis / 60000);
  var seconds = ((millis % 60000) / 1000).toFixed(0);
  return minutes + ":" + (seconds < 10 ? '0' : '') + seconds;
}

millisToMinutesAndSeconds(298999); // "4:59"
millisToMinutesAndSeconds(60999);  // "1:01"

As User HelpingHand pointed in the comments the return statement should be:

return (
  seconds == 60 ?
  (minutes+1) + ":00" :
  minutes + ":" + (seconds < 10 ? "0" : "") + seconds
);

OTHER TIPS

With hours, 0-padding minutes and seconds:

var ms = 298999;
var d = new Date(1000*Math.round(ms/1000)); // round to nearest second
function pad(i) { return ('0'+i).slice(-2); }
var str = d.getUTCHours() + ':' + pad(d.getUTCMinutes()) + ':' + pad(d.getUTCSeconds());
console.log(str); // 0:04:59

I'm not really sure why these answers are all so complex. The Date class gives you what you need:

const date = new Date(298999);

alert(`${date.getMinutes()}:${date.getSeconds()}`);

Although the above meets op's requirements, adding this updated version in response to @ianstarz comment regarding timezone independence:

const d = new Date(Date.UTC(0,0,0,0,0,0,298999)),
  // Pull out parts of interest
  parts = [
    d.getUTCHours(),
    d.getUTCMinutes(),
    d.getUTCSeconds()
  ],
  // Zero-pad
  formatted = parts.map(s => String(s).padStart(2,'0')).join(':');

document.write(formatted);

Here's my contribution if looking for

h:mm:ss

instead like I was:

function msConversion(millis) {
  let sec = Math.floor(millis / 1000);
  let hrs = Math.floor(sec / 3600);
  sec -= hrs * 3600;
  let min = Math.floor(sec / 60);
  sec -= min * 60;

  sec = '' + sec;
  sec = ('00' + sec).substring(sec.length);

  if (hrs > 0) {
    min = '' + min;
    min = ('00' + min).substring(min.length);
    return hrs + ":" + min + ":" + sec;
  }
  else {
    return min + ":" + sec;
  }
}

Event though ,oment.js does not provide such functionality, if you come here and you are already using moment.js, try this:

function formatDuration(ms) {
  var duration = moment.duration(ms);
  return Math.floor(duration.asHours()) + moment.utc(duration.asMilliseconds()).format(":mm:ss");
}

You will get something like x:xx:xx.

In the case you may want to skip the hour, when the duration is only < 60minutes.

function formatDuration(ms) {
  var duration = moment.duration(ms);
  if (duration.asHours() > 1) {
    return Math.floor(duration.asHours()) + moment.utc(duration.asMilliseconds()).format(":mm:ss");
  } else {
    return moment.utc(duration.asMilliseconds()).format("mm:ss");
  }
}

This workaround in moment was introduced in this Issue.

Best is this!

function msToTime(duration) {
var milliseconds = parseInt((duration%1000))
    , seconds = parseInt((duration/1000)%60)
    , minutes = parseInt((duration/(1000*60))%60)
    , hours = parseInt((duration/(1000*60*60))%24);

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

return hours + ":" + minutes + ":" + seconds + "." + milliseconds;
}

It will return 00:04:21.223 You can format this string then as you wish.

There is probably a better way to do this, but it gets the job done:

var ms = 298999;
var min = ms / 1000 / 60;
var r = min % 1;
var sec = Math.floor(r * 60);
if (sec < 10) {
    sec = '0'+sec;
}
min = Math.floor(min);
console.log(min+':'+sec);

Not sure why you have the << operator in your minutes line, I don't think it's needed just floor the minutes before you display.

Getting the remainder of the minutes with % gives you the percentage of seconds elapsed in that minute, so multiplying it by 60 gives you the amount of seconds and flooring it makes it more fit for display although you could also get sub-second precision if you want.

If seconds are less than 10 you want to display them with a leading zero.

function msToHMS( ms ) {
  // 1- Convert to seconds:
  var seconds = ms / 1000;

  // 2- Extract hours:
  var hours = parseInt( seconds / 3600 ); // 3,600 seconds in 1 hour
  seconds = seconds % 3600; // seconds remaining after extracting hours

  // 3- Extract minutes:
  var minutes = parseInt( seconds / 60 ); // 60 seconds in 1 minute

  // 4- Keep only seconds not extracted to minutes:
  seconds = seconds % 60;

  //alert( hours+":"+minutes+":"+seconds);
  hours = (hours < 10) ? "0" + hours : hours;
  minutes = (minutes < 10) ? "0" + minutes : minutes;
  seconds = (seconds < 10) ? "0" + seconds : seconds;
  var hms = hours+":"+minutes+":"+seconds;
  return hms;
}

If you do not need support for hours, there's a clever little way of doing this with momentjs and dayjs.

dayjs(ms).format("mm:ss")

or

moment(ms).format("mm:ss")

A millisecond timestamp passed to MomentJS and DayJS will be interpreted as the number of milliseconds since the Unix Epoch, therefore any time duration not affected by timezone (ie any number of milliseconds less than one hour) will be interpreted correctly.

Just works:

const minute = Math.floor(( milliseconds % (1000 * 60 * 60)) / (1000 * 60));

const second = Math.floor((ms % (1000 * 60)) / 1000);
const Minutes = ((123456/60000).toFixed(2)).replace('.',':');

//Result = 2:06

We divide the number in milliseconds (123456) by 60000 to give us the same number in minutes, which here would be 2.0576.

toFixed(2) - Rounds the number to nearest two decimal places, which in this example gives an answer of 2.06.

You then use replace to swap the period for a colon.

My solution: Input: 11381 (in ms) Output: 00 : 00 : 11.381

 timeformatter(time) {
    console.log(time);

    let miliSec = String(time%1000);
    time = (time - miliSec)/1000;
    let seconds = String(time%60);
    time = (time - seconds)/60;
    let minutes = String(time%60);
    time = (time-minutes)/60;
    let hours = String(time)

    while(miliSec.length != 3 && miliSec.length<3 && miliSec.length >=0) {
        miliSec = '0'+miliSec;
    }
    while(seconds.length != 2 && seconds.length<3 && seconds.length >=0) {
        seconds = '0'+seconds;
    }
    while(minutes.length != 2 && minutes.length<3 && minutes.length >=0) {
        minutes = '0'+minutes;
    }
    while(hours.length != 2 && hours.length<3 && hours.length >=0) {
        hours = '0'+hours;
    }
    return `${hours}  : ${minutes} : ${seconds}.${miliSec}`
}

this code will do a better job if you want to show hours, and centiseconds or miliseconds after seconds like 1:02:32.21 and if used in a cell phone the timer will show correct timing even after screen lock.

<div id="timer" style="font-family:monospace;">00:00<small>.00</small></div>

<script>
var d = new Date();
var n = d.getTime();
var startTime = n;

var tm=0;
function updateTimer(){
  d = new Date();
  n = d.getTime();
  var currentTime = n;  
  tm = (currentTime-startTime);
  
  //tm +=1; 
  // si el timer cuenta en centesimas de segundo
  //tm = tm*10;
  
  var hours = Math.floor(tm / 1000 / 60 / 60);
  var minutes = Math.floor(tm / 60000) % 60;
  var seconds =  ((tm / 1000) % 60);
  // saca los decimales ej 2 d{0,2}
  var seconds = seconds.toString().match(/^-?\d+(?:\.\d{0,-1})?/)[0];
  var miliseconds = ("00" + tm).slice(-3);
  var centiseconds;

  
  // si el timer cuenta en centesimas de segundo
  //tm = tm/10;


  centiseconds = miliseconds/10;
  centiseconds = (centiseconds).toString().match(/^-?\d+(?:\.\d{0,-1})?/)[0];

  minutes = (minutes < 10 ? '0' : '') + minutes;
  seconds = (seconds < 10 ? '0' : '') + seconds;
  centiseconds = (centiseconds < 10 ? '0' : '') + centiseconds;
  hours = hours + (hours > 0 ? ':' : '');
  if (hours==0){
    hours='';
  }

  document.getElementById("timer").innerHTML = hours + minutes + ':' + seconds + '<small>.' + centiseconds + '</small>';
}

var timerInterval = setInterval(updateTimer, 10);
// clearInterval(timerInterval);
</script>

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top