JavaScript将秒转换为格式为hh:mm:ss的时间字符串

415

我想将时间长度(即秒数)转换为冒号分隔的时间字符串(hh:mm:ss)。

我在这里找到了一些有用的答案,但它们都是关于转换为x小时和x分钟格式的。

那么有没有一个小片段可以在jQuery或纯JavaScript中实现此操作?


15
此线程提供的一些答案的基准测试结果。 http://jsperf.com/ms-to-hh-mm-ss-time-format - Claudijo
可能是将秒转换为HH-MM-SS的JavaScript?的重复问题。 - KyleMit
47个回答

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

您现在可以这样使用它:
alert("5678".toHHMMSS());

工作示例:

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


26
使用"%"操作符 >> 变量分钟 = Math.floor((sec_num % 3600) / 60); 变量秒钟 = Math.floor(sec_num % 60); - IvanM
3
谢谢。在将整数转为字符串之前,我认为它不能双向工作,你需要使用 .toString() 方法。你也可以通过解析 int 来实现相反的操作。 - Sonic Soul
90
不要将其放在原型中,只需制作一个实用函数即可。 - Michael J. Calkins
44
修改原型设计?390个赞?真的吗? - Lukas Liesis
3
这会在某些值下失败,导致秒数显示为60。例如00:14:60。对于这个解决方案收到如此高的赞成票感到惊讶,似乎没有人真正彻底测试过它。 - Johann
显示剩余14条评论

366
你可以使用JS Date方法来实现此操作,而无需任何外部JS库。示例代码如下:
var currentDate = new Date();
var year = currentDate.getFullYear();
var month = ('0' + (currentDate.getMonth() + 1)).slice(-2);
var day = ('0' + currentDate.getDate()).slice(-2);
var formattedDate = year + '-' + month + '-' + day;
console.log(formattedDate);

var date = new Date(0);
date.setSeconds(45); // specify value for SECONDS here
var timeString = date.toISOString().substring(11, 19);
console.log(timeString)


13
为什么这个答案的赞成数这么低?我知道这是2011年的问题,可能是因为IE 7和8不支持它,但现在已经是2014年底了,所以这个简单明了、没有烦琐的解决方案应该有更高的赞成数。 - Emil Borconi
73
我喜欢这个答案。它甚至可以更简短:new Date(1000 * seconds).toISOString().substr(11, 8) - Bohumir Zamecnik
11
不错的回答。您可以在 substr 后面使用 .replace(/^[0:]+/, ""),以删除字符串开头的所有零和冒号。 - Palo
6
在前面添加以下内容以处理超过24小时的时间: parseInt(d / 86400) + "d " - Tofandel
35
如果持续时间超过23:59:59,这个会出问题。 - sim642
显示剩余5条评论

84

为了以 hh:MM:ss 格式获取时间部分,您可以使用以下正则表达式:

(此前在同一帖子中有人提到过,感谢那位用户。)

    var myDate = new Date().toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");
    console.log(myDate)


8
+1 - 非常简单易懂,谢谢!我只想显示分钟和秒数,使用了此代码的变体: var myDate = new Date().toTimeString().replace(/.*(\d{2}:\d{2})(:\d{2}).*/, "$1"); - Topher Fangio
1
难道不应该是 "new Date(null, null, null, null, null, timeInSecs).toTimeString().replace(/.(\d{2}:)(\d{2}:\d{2})./, "$2")" 吗? - obie
6
使用replace方法让人感到困惑。为什么不使用new Date(null, null, null, null, null, timeInSeconds).toTimeString().match(/\d{2}:\d{2}:\d{2}/)[0]呢? - Călin Darie
7
这对于展示特定时间来说是可以的,但请注意问题(以及其他答案)是关于展示持续时间,即独立于当前时间的给定秒数。 - mahemoff
6
这段代码的简化版本是:new Date().toLocaleTimeString('en-US', {hour12: false}).split(':')[0] - Henrik N
显示剩余10条评论

63

我建议使用普通的JavaScript,使用Date对象。(如果要使用更短的解决方案,请参见第二个代码片段中使用toTimeString的方法。)

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

当然,创建的 Date 对象将与实际日期关联,但对于这些目的来说,该数据是无关紧要的,因此您不必担心它。


编辑(简短解决方案):

利用 toTimeString 函数并在空格上分割:

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 返回的是 '16:54:58 GMT-0800 (PST)',将其以第一个空格为分隔符进行拆分即可得到 '16:54:58'


似乎是将日期转换为本地时区,这在我的情况下会使时间增加1小时。当秒数为0时,我得到的是“01:00:00”(Thu Jan 01 1970 01:00:00 GMT+0100 (CET)),这是错误的。 - mivk
3
如果我使用 date.getUTCHours()date.getUTCMinutes(),我会得到一个正确的结果。 - mivk
7
我喜欢这个,但它假设持续时间少于24小时。 - Rory
1
在前面添加 parseInt(d / 86400) + "d " 来处理超过24小时的情况。 - Tofandel
3
时区讨厌这个。 - Ryan Leach
显示剩余4条评论

55
这是我的看法:
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
}

预期结果:
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')

3
我觉得有一个需要传递两个“second”参数的函数有点令人困惑。虽然我的版本可能有点冗长,但我认为更清晰易懂。 - Tom Esterez
1
@pstanton 自 IE9 起支持尾随逗号:https://caniuse.com/#feat=mdn-javascript_grammar_trailing_commas。我个人现在选择忽略那些旧浏览器。但你说得对,我已经将其删除,以使答案更通用。 - Tom Esterez
2
很棒的解决方案。也许只需要将秒数更改为 const s = Math.round(seconds % 60); - Raff
1
其实,你是对的。输入的秒数可能会有小数。所以我会进行更改。 - Tom Esterez
1
谢谢,这正是我在寻找的。就像YouTube的一样。 - N. Arunoprayoch
显示剩余6条评论

44

谷歌搜索得到了这个结果

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

8
secondsToTime(119.9) => Object {h: 0, m: 1, s: 60}。为了修复这个 bug,在方法开头加入 secs = Math.round(secs);。当然,在演示中我们就已经发现了这个问题... - Benjamin Crouzier

32

同一主题的变体。对单个数字秒数进行了稍微不同的处理。

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

感谢您为我节省了一个小时的时间。 - starsinmypockets

32
function formatTime(seconds) {
    return [
        parseInt(seconds / 60 / 60),
        parseInt(seconds / 60 % 60),
        parseInt(seconds % 60)
    ]
        .join(":")
        .replace(/\b(\d)\b/g, "0$1")
}

1
进一步解释为什么这个答案适用于提问者或原始问题可能存在的问题,将有助于提高此答案的质量。 - Josh Burgess
2
非常自我解释和好的答案,精简了并简化了顶级答案。 - AlexioVay
精确答案:) - Rishav Kumar
1
简短而精炼,非常好。建议在使用TypeScript时将parseInt替换为Math.floorparseInt应该有字符串输入)。 - Aaron B
1
parseInt需要一个字符串,因此seconds必须是一个字符串。在TypeScript中,如果seconds是一个数字,请使用Math.floor代替parseInt - Lee Goddard
建议:删除 parseInt,并在 .join(':') 之前加上 .map(Math.floor)。此外,为了更好的可读性,可以在 .join() 之前使用 .map(n => n.toString().padStart(2, '0')) 替换 .replace(/\b(\d)\b/g, "0$1") - Chris

15

我喜欢第一个答案。 有一些优化:

  • 源数据是数字,无需进行额外的计算。

  • 计算过度了。

结果代码:

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

1
我认为这个函数是在前端使用的特性,因此我原型化字符串而不是数字。 数字总是可以成为字符串,但反之则不行。 - powtac
4
我认为“Number”是正确的,因为“seconds”实际上是一个数字。在使用这个函数之前,你应该将其从字符串转换为数字,这样做是正确的! - caesarsol
4
点赞答案,就像这个一样,是不好的。我打赌你不需要所有数字都使用这种方法。不要修改随机实用程序的原型。 - Lukas Liesis
仅将其原型化并将其制作为函数numToHHMMSS或strTOHHMMSS。 - yeahdixon
该解决方案可行,而所选解决方案对于某些值生成60秒。 - Johann

15

使用令人惊叹的moment.js库:

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

这使您可以指定任何持续时间,无论是小时、分钟、秒还是毫秒,并返回一个易于阅读的版本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接