使用 Javascript 将毫秒转换为分秒

Soundcloud 的 API 给出了它的轨道的持续时间为毫秒:

"duration": 298999

我在这里找到了很多功能,但都没有用。我只是想找个东西把这个数字转换成像这样的东西:

4:59

有一个很接近,但是不起作用。60秒不会停止。一直到99毫无道理。例如,尝试输入“187810”作为 ms 值。

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


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

谢谢你的帮助!

如果你也能给我几个小时的支持,我会很感激的。

198357 次浏览

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


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

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.

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.

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>

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

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.

Just works:

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


const second = Math.floor((ms % (1000 * 60)) / 1000);
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;
}
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}`
}

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

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.