如何使用moment.js将秒数转换为HH:mm:ss格式

126

我如何将秒转换为HH:mm:ss格式?

目前,我正在使用以下函数:

render: function (data){
     return new Date(data*1000).toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");;
}
这在Chrome上可以工作,但在Firefox上12秒后我得到01:00:12。我想使用moment.js来实现跨浏览器兼容性。 我尝试了这个,但不起作用。
render: function (data){
         return moment(data).format('HH:mm:ss');
}

我做错了什么?

编辑

我成功地找到了一个解决方案,没有使用 moment.js,如下所示:

return (new Date(data * 1000)).toUTCString().match(/(\d\d:\d\d:\d\d)/)[0];

我仍然好奇如何在moment.js中实现它。


2
@QuentinTanioartino,所以对于数百万个元素的DOM变异任务来说,4个微不足道的数学运算符是一个问题吗?您确定您正确理解了性能问题吗? - zerkms
@zerkms,我知道我的DAO类必须重写以服务于已转换的数据。这是我知道的一个问题。话虽如此,我对第一次尝试的当前性能非常满意,但当我有5个数学运算需要进行转换时,系统会变慢一些。是的,我同意你的看法,这只是一个快速的临时解决方案。 - QGA
@QuentinTanioartino "that slows the system a bit" --- "a bit" is not how you reason about performance. 是瓶颈吗?已经被证明是瓶颈吗?如果不是-是什么驱使你优化这个操作呢? - zerkms
@mplungjan 当夏令时/冬令时边界到来时,它将失败。 - zerkms
啊,不使用moment的另一个原因是可以将开始日期设置为1月1日。 - mplungjan
显示剩余7条评论
12个回答

152

这与mplungjan从另一篇文章中提供的答案类似,但更为简洁:

const secs = 456;

const formatted = moment.utc(secs*1000).format('HH:mm:ss');

document.write(formatted);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

它受到同样的限制,例如如果秒数超过一天(86400),您将得不到您期望的结果。


1
谢谢,我认为这是一个非常普遍的需求,可以向moment.js提交一个拉取请求,他们应该会将其纳入其中。 - Morris S
谢谢@Sophie。很少有地方提到utc(),这正是我需要的。 - pmont
4
无法处理超过24小时的秒数,例如90000秒。 - TheAlphaGhost
感谢 @Sophie 的大力帮助。 - Naga Hemanth
1
@Sophie,对于较大的第二个数字无法正常工作。 - Amir Astaneh

97

这篇帖子中,我会尝试这样做以避免闰秒问题。

moment("2015-01-01").startOf('day')
    .seconds(s)
    .format('H:mm:ss');

我没有运行jsPerf,但我认为这比一百万次创建新日期对象要快。

function pad(num) {
    return ("0"+num).slice(-2);
}
function hhmmss(secs) {
  var minutes = Math.floor(secs / 60);
  secs = secs%60;
  var hours = Math.floor(minutes/60)
  minutes = minutes%60;
  return `${pad(hours)}:${pad(minutes)}:${pad(secs)}`;
  // return pad(hours)+":"+pad(minutes)+":"+pad(secs); for old browsers
}
抱歉,我目前只能以英文回答问题。
function pad(num) {
    return ("0"+num).slice(-2);
}
function hhmmss(secs) {
  var minutes = Math.floor(secs / 60);
  secs = secs%60;
  var hours = Math.floor(minutes/60)
  minutes = minutes%60;
  return `${pad(hours)}:${pad(minutes)}:${pad(secs)}`;
  // return pad(hours)+":"+pad(minutes)+":"+pad(secs); for old browsers
}

for (var i=60;i<=60*60*5;i++) {
 document.write(hhmmss(i)+'<br/>');
}


/* 
function show(s) {
  var d = new Date();
  var d1 = new Date(d.getTime()+s*1000);
  var  hms = hhmmss(s);
  return (s+"s = "+ hms + " - "+ Math.floor((d1-d)/1000)+"\n"+d.toString().split("GMT")[0]+"\n"+d1.toString().split("GMT")[0]);
}    
*/


1
在第二个例子中,您可以这样做:return [hours,minutes,seconds]。filter(t => t).map(pad).join(“:”) - Onno Faber
@OnnoFaber 你认为哪个更快?连接还是过滤加映射?我们也可以这样做:\${pad(hours)}:${pad(minutes)}:${pad(secs)}`` - mplungjan
从之前的所有答案中,最简单的是mplungjan的答案,但如果值有毫秒(例如:17.3秒),它会显示随机数字的错误。 基于他的代码,我提出以下建议:function pad(num) { return ("0" + num).slice(-2); } /** * @return {string} */ export default function renderUserTime (seconds){ let minutes = Math.floor(seconds / 60); const outputSecs = Math.round(seconds % 60); let hours = Math.floor(minutes / 60); const outputMinutes = Math.round(minutes % 60); return `${pad(hours)}:${pad(outputMi - Alberto Soto

31

你可以使用moment-duration-format插件:

var seconds = 3820;
var duration = moment.duration(seconds, 'seconds');
var formatted = duration.format("hh:mm:ss");
console.log(formatted); // 01:03:40
<!-- Moment.js library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

<!-- moment-duration-format plugin -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/1.3.0/moment-duration-format.min.js"></script>

请参考此 Fiddle 示例。

更新:为避免小于60秒的值被截断,请使用 { trim: false }

var formatted = duration.format("hh:mm:ss", { trim: false }); // "00:00:05"

你的答案和@sophie的答案需要进行权衡。虽然从技术上讲,你的解决方案将显示“时间”为hh:mm:ss,但它需要额外的插件。Sophie的是从当前时间点格式化为hh:mm:ss的“日期”。如果从Sophie的中删除“utc”,它可能会返回不正确的信息,因为它使用纪元作为日期而不是当前时间点。两个答案都可以工作。只是需要考虑和理解一下。 - Michael
虽然在这里使用CDN等工具可能会增加延迟,但是通常认为“包含另一个库”与自己实现代码相比是一种负面权衡是非常危险的。这是我看到许多开发人员陷入的陷阱,最终导致他们拥有不太可维护的代码。 - cytinus
由于某种原因,如果秒数小于60,则最终结果将无格式。 - Daniel Lizik
@DanielLizik,只需添加 { trim: false }。例如: duration.format("hh:mm:ss", { trim: false }); - Oleksiy Kachynskyy

19
var seconds = 2000 ; // or "2000"
seconds = parseInt(seconds) //because moment js dont know to handle number in string format
var format =  Math.floor(moment.duration(seconds,'seconds').asHours()) + ':' + moment.duration(seconds,'seconds').minutes() + ':' + moment.duration(seconds,'seconds').seconds();

8

我提供的解决方法是将秒数(数字)转换为字符串格式(例如:'mm:ss'):

const formattedSeconds = moment().startOf('day').seconds(S).format('mm:ss');

在示例中,使用您的秒数而不是'S',并且只需在需要时使用formattedSeconds


2
这就是我一直在寻找的答案。很好的建议,但要记住,如果你想显示小时,确保使用 HH:mm:ss 而不是 hh:mm:ss,否则在持续时间小于1小时时会得到 12:**:** - Dean Koštomaj

5

上述示例可能适用于某些人,但对我来说都不行,因此我找到了一种更简单的方法。

  var formatted = moment.utc(seconds*1000).format("mm:ss");
  console.log(formatted);

对我来说有效! :) - undefined

5

更好的使用 moments.js,您可以将秒数转换为可读性更强的格式,例如(几秒钟,2分钟,一小时)。

以下示例应将30秒转换为“几秒钟”。

moment.duration({"seconds": 30}).humanize()

其他有用的功能:"分钟","小时"


4

在24小时之前。 由于moment@2.23.0的存在,Duration.format已经被弃用。

const seconds = 123;
moment.utc(moment.duration(seconds,'seconds').as('milliseconds')).format('HH:mm:ss');

救了我!谢谢你! - Renan Coelho

1

如何正确使用moment.js的持续时间? | 在代码中使用moment.duration()

首先,您需要导入momentmoment-duration-format

import moment from 'moment';
import 'moment-duration-format';

然后,使用持续时间功能。让我们应用上面的例子:28800 = 上午8点。
moment.duration(28800, "seconds").format("h:mm a");

好的,您没有遇到上述类型错误。您是否得到了正确的值8:00 am?不是...,您得到的值是8:00 a。Moment.js格式不像应该工作的那样。

解决方案是将秒转换为毫秒并使用UTC时间。

moment.utc(moment.duration(value, 'seconds').asMilliseconds()).format('h:mm a')

现在是早上8点。如果您想要整点时间显示为8点而非8:00,我们需要使用正则表达式。
const time = moment.utc(moment.duration(value, 'seconds').asMilliseconds()).format('h:mm a');
time.replace(/:00/g, '')

0

在2022年,无需任何新插件,只需执行以下操作

实际上,您在2022年所需要的就是从两个不同的日期字符串中打印出hh:mm:ss的持续时间。

<Moment format='hh:mm:ss' duration={startTime} date={endTime} />


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