使用JavaScript将秒转换为HH-MM-SS?

Han*_*sir 203 javascript time date date-format time-format

如何HH-MM-SS使用JavaScript 将秒转换为字符串?

Har*_*chu 351

您可以使用JavaScript Date方法在没有任何外部JavaScript库的情况下执行此操作,如下所示:

var date = new Date(null);
date.setSeconds(SECONDS); // specify value for SECONDS here
var result = date.toISOString().substr(11, 8);
Run Code Online (Sandbox Code Playgroud)

  • 这甚至可以缩短为一行:`new Date(SECONDS*1000).toISOString().substr(11,8);` (92认同)
  • 这种方法的问题是它会在24小时后溢出,阻止您显示超过这段时间.如果您的秒数少于24小时,则是完美的解决方案. (38认同)
  • 我不知道为什么每个人都在添加额外的库或在完美运行时手动进行数学运算.谢谢! (36认同)
  • 辉煌.没有任何第三方lib.这是最好的 (4认同)
  • 这在 IE11 中对我不起作用,我得到`对象不支持属性或方法'toISOString'` (2认同)

T.J*_*der 133

我认为标准Date对象的任何内置功能都不会以比自己进行数学运算更方便的方式为您执行此操作.

hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
minutes = Math.floor(totalSeconds / 60);
seconds = totalSeconds % 60;
Run Code Online (Sandbox Code Playgroud)

例:

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);
Run Code Online (Sandbox Code Playgroud)

  • @HannounYassir`console.log(小时+':'+('0'+分钟).slice(-2)+':'+('0'+秒).slice(-2));` (8认同)
  • 喔好吧!改变了我的代码。尽管您可能也希望在秒内使用它:`seconds = Math.floor(totalSeconds % 60);`。我也在那里得到了一个十进制结果。 (3认同)

Cle*_*ton 100

你不知道datejs吗?这是必须知道的.

使用datejs,只需写下:

(new Date).clearTime()
          .addSeconds(15457)
          .toString('H:mm:ss');
Run Code Online (Sandbox Code Playgroud)

--update

现在date.js已经过时而没有维护,所以请使用" Moment.js ",这比TJ Crowder指出要好得多.

  • 授予Moment.js并不是那么大,但如果您正在做的就是将秒转换为hh:mm:ss,这似乎有点过分.而是使用这些或其他答案中建议的功能之一. (15认同)
  • @Yassir和Cleiton:FWIW,DateJS多年来一直没有维护,并且确实有一些突出的错误(尽管据我所知,它们主要是解析和午夜).[momentjs](http://momentjs.com/)似乎相当不错,目前正在维护. (10认同)
  • 为一个简单的操作添加库我认为不应该被接受的答案。是的,这可行,但还有更好的解决方案! (5认同)
  • 如果有的话,这个答案是部分错误的。如果数量超过 86400 秒会发生什么?;) (3认同)
  • 我认为其他解决方案比在混合中添加另一个js库更好。 (3认同)
  • 使用这个库来完成这样的一项小任务会为您的项目添加 **`59,024 字节`**,以获得与大约 **`53 字节`** 相同的效果。。。来自[下面](/sf/answers/1769553831/): `new Date(SECONDS * 1000).toISOString().substr(11, 8);` (3认同)
  • 只要你的工作时间不超过...24? (3认同)
  • 这完全是错误的!正如其他人指出的那样,如果您有超过一天的时间,那么答案就是不正确的。谨慎使用!请参阅下面圣地亚哥·埃尔南德斯的回答。 (2认同)

San*_*dez 40

我知道这有点老了,但......

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(":")
}
Run Code Online (Sandbox Code Playgroud)

它将输出:

toHHMMSS(129600) // 36:00:00
toHHMMSS(13545) // 03:45:45
toHHMMSS(180) // 03:00
toHHMMSS(18) // 00:18
Run Code Online (Sandbox Code Playgroud)

  • +1。这个或 TJ 应该是可接受的答案,因为它们是唯一适用于持续时间超过 24 小时的情况的答案(并且问题不限制持续时间)。 (6认同)
  • 几分之一秒呢?03:45:45.xxx? (2认同)
  • @SantiagoHernández 太棒了!这现在可以完美地工作超过 24 小时。 (2认同)

Der*_*ler 33

正如Cleiton在他的回答中指出的那样,moment.js可用于此:

moment().startOf('day')
        .seconds(15457)
        .format('H:mm:ss');
Run Code Online (Sandbox Code Playgroud)

  • 如果秒数超过一年会怎样? (9认同)
  • 如果秒数超过一天会怎样? (5认同)
  • @GiladPeleg如果秒数超过一天,则内部计算天数,并且仅返回剩余的小时,分​​钟和秒.如果你想计算天数,你可以尝试`moment().startOf('year').seconds(30000000).format('DDD HH:mm:ss')`. (3认同)
  • @OrangePot如果秒数超过一年,则内部计算年数,并且仅返回剩余的天,小时,分钟和秒。如果您还想计算年数,可以尝试`.format('YYYY DDD HH:mm:ss')` (3认同)

Dim*_* L. 19

function formatSeconds(seconds)
{
    var date = new Date(1970,0,1);
    date.setSeconds(seconds);
    return date.toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你超过24小时不起作用 (4认同)
  • formatSeconds(3919); //返回01:05:19优秀的功能..喜欢它 (2认同)

Wag*_*ers 16

这样做的诀窍:

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;
}
Run Code Online (Sandbox Code Playgroud)

(来自这里)


Pet*_*ský 12

我认为最通用(且神秘)的解决方案可能是这样的

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('-');
}
Run Code Online (Sandbox Code Playgroud)

或者复制并粘贴最短的版本

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('-');
}
Run Code Online (Sandbox Code Playgroud)

一些示例输出:

> 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"
Run Code Online (Sandbox Code Playgroud)

怎么运行的

算法

  1. 要获得小时数,请将总秒数除以 3600 并将其取整。
  2. 要获得分钟数,请将余数除以 60,然后将其取整。
  3. 要获得秒数,只需使用余数即可。

将各个金额保存在数组中以便于格式化也很好。

例如,输入 3785 秒,输出应为[1, 3, 5],即 1 小时 3 分 5 秒。

创建管道

将 3600 和 60 常量命名为“断点”,您可以将此算法写入函数中,如下所示

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

它返回一个数组,其中第一项是给定断点的数量,数组的其余部分由回调给出。重用divideAndAppendin 回调函数将为您提供一个组合 divideAndAppend函数的管道。其中每一个都会计算每个给定断点的数量并将其附加到数组中以生成所需的输出。

然后,您还需要结束该管道的“最终”回调。换句话说,您使用了所有断点,现在只剩下剩余的断点。由于您已经在 3) 处得到了答案,因此您应该使用某种恒等函数,在本例中为remainder => [remainder]

您现在可以像这样编写管道

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

> pipeline(3785)
< [1, 3, 5]
Run Code Online (Sandbox Code Playgroud)

很酷吧?

使用 for 循环进行泛化

现在,您可以使用可变数量的断点进行概括,并创建一个 for 循环,将各个divideAndAppend函数组合到管道中。您从恒等函数开始r1 => [r1],然后使用60断点,最后使用3600断点。

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]
Run Code Online (Sandbox Code Playgroud)

使用Array.prototype.reduce()

现在,您可以将此 for 循环重写为 reducer,以获得更短、更实用的代码。换句话说,将函数组合重写到reducer 中。

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

> pipeline(3785)
< [1, 3, 5]
Run Code Online (Sandbox Code Playgroud)

累加器ppln是管道,您正在使用它的早期版本来编写它。初始管道是r => [r].

您现在可以内联该函数divideAndAppend并使用与Array.prototype.reduceRight相同的功能来[].reverse().reduce(...)使断点定义更加自然。

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

这是最终的形式。然后,您只需应用映射到左侧填充 0 的字符串,并使用分隔符连接字符串即可:

更多概括

将减速器包装到函数中

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]
Run Code Online (Sandbox Code Playgroud)

现在你已经有了可以使用的非常通用的算法。例如:

轻松转换(奇怪的)美国长度标准

鉴于标准

单元 部门
1 英尺 12英寸
1码 3英尺
1 英里 1760 码
> decompose(123_456, [1760 * 3 * 12, 3 * 12, 12])
< [1, 1669, 1, 0]
Run Code Online (Sandbox Code Playgroud)

123456 英寸 = 1 英里、1669 码、1 英尺和 0 英寸

或者您可以稍微转换为十进制或二进制表示形式

> 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]
Run Code Online (Sandbox Code Playgroud)

也适用于浮点断点

由于Javascript支持mod浮点数运算符,你也可以这样做

> decompose(26.5, [20, 2.5])
< [1, 2, 1.5]
Run Code Online (Sandbox Code Playgroud)

无断点的边缘情况也自然被覆盖

> decompose(123, [])
< [123]
Run Code Online (Sandbox Code Playgroud)


she*_*riy 10

     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"
Run Code Online (Sandbox Code Playgroud)

我们可以使这个功能更短更清晰,但这会降低可读性,因此我们将尽可能简单地编写并尽可能稳定.

或者你可以在这里查看这个:


Hun*_* Vo 9

试试这个:

function toTimeString(seconds) {
  return (new Date(seconds * 1000)).toUTCString().match(/(\d\d:\d\d:\d\d)/)[0];
}
Run Code Online (Sandbox Code Playgroud)


Bur*_*kan 6

这是Number类的扩展.toHHMMSS()将秒转换为hh:mm:ss字符串.

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();
Run Code Online (Sandbox Code Playgroud)
// HTML of the test
<div id="timespan"></div>
Run Code Online (Sandbox Code Playgroud)


Col*_*ris 5

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);
Run Code Online (Sandbox Code Playgroud)


Joh*_*ers 5

这个函数应该做到这一点:

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 : ':' );
}
Run Code Online (Sandbox Code Playgroud)

在不传递分隔符的情况下,它:用作(默认)分隔符:

time = convertTime(13551.9941351); // --> OUTPUT = 03:45:51
Run Code Online (Sandbox Code Playgroud)

如果要-用作分隔符,只需将其作为第二个参数传递:

time = convertTime(1126.5135155, '-'); // --> OUTPUT = 00-18-46
Run Code Online (Sandbox Code Playgroud)

另请参见此Fiddle


小智 5

在这个旧线程中加入 - OP 声明为 HH:MM:SS,并且许多解决方案都有效,直到您意识到需要列出 24 小时以上。也许您只需要一行代码。干得好:

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

它返回 H+:MM:SS。要使用它,只需使用:

d(91260);     // returns "25:21:00"
d(960);       // returns "0:16:00"
Run Code Online (Sandbox Code Playgroud)

...我试图让它使用尽可能少的代码,以获得一种很好的单行方法。


NVR*_*VRM 5

对于FFMPEG用于指定毫秒HH:MM:SS.MS (eq: "00:04:33.637")的特殊情况。

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

HH 表示小时数,MM 表示分钟数,最多 2 位,SS 表示秒数,最多 2 位。末尾的 m 表示 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)
)
Run Code Online (Sandbox Code Playgroud)

示例用法,毫秒传输计时器:

/* 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)
Run Code Online (Sandbox Code Playgroud)
span {font-size:4rem}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

示例用法,绑定到媒体元素

/* 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)
Run Code Online (Sandbox Code Playgroud)
span {font-size:4rem}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


在问题之外,用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];  
}
Run Code Online (Sandbox Code Playgroud)