如何在 moment.js 持续时间内使用 format()?
Posted
技术标签:
【中文标题】如何在 moment.js 持续时间内使用 format()?【英文标题】:How to use format() on a moment.js duration? 【发布时间】:2012-10-27 02:09:35 【问题描述】:有什么方法可以在持续时间对象上使用moment.jsformat
方法吗?我在文档中的任何地方都找不到它,而且它也不是持续时间对象的属性。
我希望能够做类似的事情:
var diff = moment(end).unix() - moment(start).unix();
moment.duration(diff).format('hh:mm:ss')
另外,如果有任何其他库可以轻松容纳此类功能,我会对推荐感兴趣。
谢谢!
【问题讨论】:
moment.utc(duration.asMilliseconds()).format('hh:mm:ss'); - 持续时间是一个向量。通过将其尾部放在原点上,您可以使用日期格式来获取 hh:mm:ss。 moment.utc(moment.duration(23, 'seconds').asMilliseconds()).format('hh:mm:ss') => "12:00:23" 没有工作得很好 啊,我发现了问题,HH:mm:ss
将在我之前的示例中给出00:00:23
。所以只是小时部分的错误大小写
【参考方案1】:
// set up
let start = moment("2018-05-16 12:00:00"); // some random moment in time (in ms)
let end = moment("2018-05-16 12:22:00"); // some random moment after start (in ms)
let diff = end.diff(start);
// execution
let f = moment.utc(diff).format("HH:mm:ss.SSS");
alert(f);
Have a look at the JSFiddle
【讨论】:
好方法。尽管如果我也想显示日期,它也不起作用:DDD HH:mm:ss.SSS
(其中DDD
是一年中的某天)在我想要0
时显示1
。有什么快速解决办法吗?
不容易。我做了这个 jsfiddle.net/fhdd8/14 ,这可能是你所做的,但我不认为 moment 有任何开箱即用的东西
将 10 万亿毫秒显示为 mm:ss 没有任何意义
这在 24 小时后不起作用(即,如果我想显示 117 小时)。否则很好的解决方案!
@Phil 如果您想显示天数,可以使用“D”或“DD”。【参考方案2】:
将持续时间转换为毫秒,然后转换为时刻:
moment.utc(duration.as('milliseconds')).format('HH:mm:ss')
【讨论】:
因此,如果您的持续时间超过 24 小时,这将不起作用.. 24 小时被重置为 0 小时 @S.Robijns 是一个有用的观察,但只是为了向其他人强调 - 这 是.format('HH:mm:ss')
的预期行为。 See the docs【参考方案3】:
我们正在考虑在 moment.js 中为持续时间添加某种格式。见https://github.com/timrwood/moment/issues/463
http://countdownjs.org/ 和 https://github.com/icambron/twix.js 等其他几个库可能会有所帮助
【讨论】:
我也期待持续时间格式。现在看一下 countdownjs,但 twix 似乎只做“智能”格式化,没有太多自定义。 虽然 twix 努力进行智能格式化,但它有很多格式化选项,包括所涉及的标记:github.com/icambron/twix.js/wiki/Formatting。免责声明:我是 twix 的作者。 Countdown.js 非常好,作者超好用(因为我的一些建议,他当天才发布2个版本)! 我投了反对票,因为这个答案中链接的 github 问题只是一个永无止境的意见、愿望和咆哮,无处可去,4 年后问题仍然存在,没有任何用处 为什么它不能与库中其他地方使用的其他 .format 相同?这是精神错乱。 5年了还没有完成?真的吗?!【参考方案4】:使用这个插件Moment Duration Format。
例子:
moment.duration(123, "minutes").format("h:mm");
【讨论】:
该格式无法正常工作,持续时间方面很好,但如果我指定hh:mm:mm
并且只有 10 秒,它会显示 10
而不是 00:00:10
(即使打开 forcelength)如果它不是格式化......那么它应该被称为别的东西,格式应该是标准化的。
@ppumkin 我知道这是旧的,但如果你指定 trim: false
它将停止这种行为。
这是我更喜欢使用的:假设你有持续时间,比如const duration = moment.duration(value, 'seconds');
,而不是我可以使用格式化:moment.utc(duration.as('milliseconds')).format('HH:mm:ss').toString();
@EvgenyBobkin 如果您的持续时间超过一天,它将无法工作,但图书馆会处理它【参考方案5】:
使用这行代码:
moment.utc(moment.duration(4500, "seconds").asMilliseconds()).format("HH:mm:ss")
【讨论】:
如果持续时间 > of 86400''(即 24 小时),这将不起作用。 excel中也是一样,24小时翻转。如果您知道 24 小时限制,这是一个很好的解决方法。 所以当我使用 .utc 时,时间是 waaaaayyyy 关闭。为什么?【参考方案6】:var diff = moment(end).unix() - moment(start).unix();
moment.utc(moment.duration(diff).asMilliseconds()).format("HH:mm:ss.SSS");
【讨论】:
一般来说,如果答案包括对代码的用途的解释,以及为什么在不介绍其他人的情况下解决问题的原因,答案会更有帮助。 (该帖子至少被一位用户标记,大概是因为他们认为应该删除没有解释的答案。) 无法解释,这对我来说是什么。谢谢:) 不需要解释。 Moment.js 文档可以展示这个解决方案是如何实现的。 没用。像这个问题的大多数其他答案一样,返回持续时间的部分小时而不是总小时。例如。持续时间返回 12:00 moment.duration(days: 2, hours: 12) moment.duration(diff).asMilliseconds() 过多。您可以只使用 diff,它已经在毫秒内。【参考方案7】:我的特定用例的最佳方案是:
var duration = moment.duration("09:30"),
formatted = moment.utc(duration.asMilliseconds()).format("HH:mm");
这改进了 @Wilson 的回答,因为它不访问私有内部属性 _data。
【讨论】:
【参考方案8】:您不需要 .format。像这样使用持续时间:
const duration = moment.duration(83, 'seconds');
console.log(duration.minutes() + ':' +duration.seconds());
// output: 1:23
我在这里找到了这个解决方案:https://github.com/moment/moment/issues/463
编辑:
还有秒、分和小时的填充:
const withPadding = (duration) =>
if (duration.asDays() > 0)
return 'at least one day';
else
return [
('0' + duration.hours()).slice(-2),
('0' + duration.minutes()).slice(-2),
('0' + duration.seconds()).slice(-2),
].join(':')
withPadding(moment.duration(83, 'seconds'))
// 00:01:23
withPadding(moment.duration(6048000, 'seconds'))
// at least one day
【讨论】:
如果 duration.seconds() 小于 10,这将不包括前导零... 如果秒数超过一小时会怎样?那么你有超过 60 秒的时间可以吗? 前导零有效,但duration = moment.duration(7200, 'seconds'); withPadding(duration);
会说“00:00”。
@shaedrich 我再次更新了我的答案以包括小时数;如果您需要几天、几周,也可以将它们添加到数组中
if (duration.asDays() > 0) return 'at least one day';
- 我读对了吗?【参考方案9】:
我用:
var duration = moment.duration("09:30");
var str = moment(duration._data).format("HH:mm");
我在 var str 中得到“09:30”。
【讨论】:
太棒了!这只是工作......你到底是怎么想出这个的:) 避免这种解决方案,_data
是一个内部属性,可能会在没有警告的情况下更改。
不幸的是,它不会总是按预期工作:moment(moment.duration(1200000)._data).format('hh:mm:ss')
将返回 12:20 而不是 00:20
@AnnaR h
在 1-12 范围内,所以这是可以预料的。使用H
而不是docs - hour tokens
这是错误的,不仅你忽略了DAYS,所以1day和1hour会显示为01:00。此外,您完全忽略了时区,这是一个更好的解决方案,但 也不是完整的 将是 moment.utc(...).format("HH:mm");
【参考方案10】:
我需要这样做以作为以这种格式显示小时数的要求。 一开始我试过这个。
moment.utc(totalMilliseconds).format("HH:mm:ss")
但是,超过 24 小时的任何时间都将重置为 0。 但分钟和秒是准确的。 所以我只用那部分来表示分钟和秒。
var minutesSeconds = moment.utc(totalMilliseconds).format("mm:ss")
现在我只需要总小时数。
var hours = moment.duration(totalMilliseconds).asHours().toFixed()
为了获得我们都想要的格式,我们只需将它们粘合在一起即可。
var formatted = hours + ":" + minutesSeconds
如果totalMilliseconds
是894600000
,这将返回249:30:00
。
希望对您有所帮助。在 cmets 中留下任何问题。 ;)
【讨论】:
不会'toFixed()' 将数字四舍五入吗?例如:“76.35”将变为“77”,而您想要的是“76”,然后将小时和分钟附加到它上面。我使用了 var hours = Math.floor(moment.duration(totalMilliseconds).asHours())。代码中的其他所有内容都很酷。感谢您的回答。【参考方案11】:如果差异是一瞬间
var diff = moment(20111031) - moment(20111010);
var formated1 = moment(diff).format("hh:mm:ss");
console.log("format 1: "+formated1);
【讨论】:
面对时区等,这似乎并不可靠。你在生产中使用它吗? 这个问题没有提到时区。 每个人都生活在一个时区。时刻(0)是否总是在每个时区注册为 12:00 AM? 我只是询问您答案中的代码是否有效,因为我持怀疑态度。我用许多编程语言编写了很多与日期一起使用的代码。根据我的经验,您的代码似乎只能在某些时区工作——但我之所以这么问,是因为我可能不知道 javascript 如何表示 Unix 时代附近的日期。 第二行将创建一个从时间开始(1970)开始的时刻。这不行。【参考方案12】:如果您愿意使用不同的 javascript 库,numeral.js 可以将秒格式化如下(示例为 1000 秒):
var string = numeral(1000).format('00:00');
// '00:16:40'
【讨论】:
绝对是要走的路。正如预期的那样。【参考方案13】:如果必须显示所有小时数(超过 24 个)并且如果小时数之前不需要“0”,则可以使用一小行代码进行格式化:
Math.floor(duration.as('h')) + moment.utc(duration.as('ms')).format(':mm:ss')
【讨论】:
这是最好的 h:mm 答案,但我认为最好的显示只是moment.duration(val,'seconds').humanize()
。
对于我的用例,用mm
和ss
显示所有小时是最好的方法,因为它很紧凑,看起来类似于逗号分隔的值,因此有利于视觉比较。
【参考方案14】:
基于ni-ko-o-kin's answer:
meassurements = ["years", "months", "weeks", "days", "hours", "minutes", "seconds"];
withPadding = (duration) =>
var step = null;
return meassurements.map((m) => duration[m]()).filter((n,i,a) =>
var nonEmpty = Boolean(n);
if (nonEmpty || step || i >= a.length - 2)
step = true;
return step;
).map((n) => ('0' + n).slice(-2)).join(':')
duration1 = moment.duration(1, 'seconds');
duration2 = moment.duration(7200, 'seconds');
duration3 = moment.duration(604800, 'seconds');
withPadding(duration1); // 00:01
withPadding(duration2); // 02:00:00
withPadding(duration3); // 01:07:00:00:00
【讨论】:
我不认为它的可读性很强。你想在这里解决什么问题?你的用例是什么? 我再次更新了我的答案以处理超过一天。它适用于我的用例。 问题在于,在大多数情况下,您的解决方案并不理想,因为它包含太多前导零。谁想要返回“00:00:00:00:01”?我的解决方案是“可扩展的”,并根据需要添加尽可能多的前导零。 完美运行。非常简单的输出。如果没有天数,则显示天数等不会为零。【参考方案15】:在这些情况下我使用经典的格式化功能:
var diff = moment(end).unix() - moment(start).unix();
//use unix function instead of difference
moment.unix(diff).format('hh:mm:ss')
这是一个 hack,因为时间差异被视为标准时刻日期,早期纪元日期时间,但这与我们的目标无关,您不需要任何插件
【讨论】:
【参考方案16】:将持续时间格式化为字符串
var duration = moment.duration(86400000); //value in milliseconds
var hours = duration.hours();
var minutes = duration.minutes();
var seconds = duration.seconds();
var milliseconds = duration.milliseconds();
var date = moment().hours(hours).minutes(minutes).seconds(seconds).millisecond(milliseconds);
if (is12hr)
return date.format("hh:mm:ss a");
else
return date.format("HH:mm:ss");
【讨论】:
【参考方案17】:如果您使用 Angular,请将其添加到您的过滤器中:
.filter('durationFormat', function ()
return function (value)
var days = Math.floor(value/86400000);
value = value%86400000;
var hours = Math.floor(value/3600000);
value = value%3600000;
var minutes = Math.floor(value/60000);
value = value%60000;
var seconds = Math.floor(value/1000);
return (days? days + ' days ': '') + (hours? hours + ' hours ': '') + (minutes? minutes + ' minutes ': '') + (seconds? seconds + ' seconds ': '')
)
使用示例
<div> diff | durationFormat </div>
【讨论】:
确实很好。我一直在寻找这样的“漂亮格式”。谢谢!【参考方案18】:我的解决方案不涉及任何其他库,它适用于 diff > 24h
var momentInSeconds = moment.duration(n,'seconds')
console.log(("0" + Math.floor(momentInSeconds.asHours())).slice(-2) + ':' + ("0" + momentInSeconds.minutes()).slice(-2) + ':' + ("0" + momentInSeconds.seconds()).slice(-2))
【讨论】:
【参考方案19】:原生 javascript 怎么样?
var formatTime = function(integer)
if(integer < 10)
return "0" + integer;
else
return integer;
function getDuration(ms)
var s1 = Math.floor(ms/1000);
var s2 = s1%60;
var m1 = Math.floor(s1/60);
var m2 = m1%60;
var h1 = Math.floor(m1/60);
var string = formatTime(h1) +":" + formatTime(m2) + ":" + formatTime(s2);
return string;
【讨论】:
【参考方案20】:moment.duration(x).format()
已被弃用。
您可以使用moment.utc(4366589).format("HH:mm:ss")
来获得所需的响应。
console.log(moment.utc(4366589).format("HH:mm:ss"))
<script src="https://momentjs.com/downloads/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
【讨论】:
【参考方案21】:如何正确使用 moment.js 持续时间? | 在代码中使用 moment.duration()
首先你需要导入moment
和moment-duration-format
。
import moment from 'moment';
import 'moment-duration-format';
然后,使用持续时间函数。让我们应用上面的例子:28800 = 8 am。
moment.duration(28800, "seconds").format("h:mm a");
?好吧,你没有上述类型错误。 ?早上 8:00 得到正确的值吗?不……,您得到的值是 8:00 a。 Moment.js 格式无法正常工作。
?解决方法是将秒转换为毫秒,并使用UTC时间。
moment.utc(moment.duration(value, 'seconds').asMilliseconds()).format('h:mm a')
好的,我们现在是上午 8:00。如果你想要 8 am 而不是 8:00 am 作为整数时间,我们需要做 RegExp
const time = moment.utc(moment.duration(value, 'seconds').asMilliseconds()).format('h:mm a');
time.replace(/:00/g, '')
【讨论】:
【参考方案22】:短版(单行):
moment.duration(durationInMs).asHours()|0||"00" + ":" + moment.utc(durationInMs).format("mm:ss")
加长版:
export const formatDuration = (durationInMs) =>
const hours = Math.floor(moment.duration(durationInMs).asHours()) || "00"
return hours + ":" + moment.utc(durationInMs).format("mm:ss")
例子:
【讨论】:
【参考方案23】:使用moment-duration-format。
客户端框架(例如:React)
import moment from 'moment';
import momentDurationFormatSetup from 'moment-duration-format';
momentDurationFormatSetup(moment);
const breakLengthInMinutes = moment.duration(breakLengthInSeconds, 's').format('m');
服务器(node.js)
const moment = require("moment-timezone");
const momentDurationFormatSetup = require("moment-duration-format");
momentDurationFormatSetup(moment);
const breakLengthInMinutes = moment.duration(breakLengthInSeconds, 's').format('m');
【讨论】:
【参考方案24】:不再需要(如果有的话)将持续时间转换为 UTC 来解决此问题。这就像将 base10 的“1”转换为二进制,然后说由于输出“1”看起来像 base10,我们假设这是一个 base10 值,可以进行任何进一步的操作。
使用moment-duration-format 并注意使用 trim: false
可以防止修剪:
moment.duration(1000000, "seconds").format("hh:mm:ss", trim: false )
> "277:46:40"
moment.duration(0, "seconds").format("hh:mm:ss", trim: false )
> "00:00:00"
我们把这个和不推荐的using滥用utc的方法对比一下:
moment.utc(moment.duration(1000000, "seconds").asMilliseconds()).format('HH:mm:ss')
> "13:46:40"
【讨论】:
【参考方案25】:const duration = moment.duration(62, 'hours');
const n = 24 * 60 * 60 * 1000;
const days = Math.floor(duration / n);
const str = moment.utc(duration % n).format('H [h] mm [min] ss [s]');
console.log(`$days > 0 ? `$days $days == 1 ? 'day' : 'days' ` : ''$str`);
打印:
2 天 14 小时 00 分 00 秒
【讨论】:
【参考方案26】:import * as moment from 'moment'
var sleep = require('sleep-promise');
(async function ()
var t1 = new Date().getTime();
await sleep(1000);
var t2 = new Date().getTime();
var dur = moment.duration(t2-t1);
console.log(`$dur.hours()h:$dur.minutes()m:$dur.seconds()s`);
)();
0h:0m:1s
【讨论】:
【参考方案27】:您可以使用numeral.js 来格式化您的时长:
numeral(your_duration.asSeconds()).format('00:00:00') // result: hh:mm:ss
【讨论】:
【参考方案28】:这可用于将前两个字符作为小时,将后两个字符作为分钟。同样的逻辑也可以应用于秒。
/**
* PT1H30M -> 0130
* @param ISO String isoString
* @return string absolute 4 digit number HH:mm
*/
const parseIsoToAbsolute = (isoString) =>
const durations = moment.duration(isoString).as('seconds');
const momentInSeconds = moment.duration(durations, 'seconds');
let hours = momentInSeconds.asHours().toString().length < 2
? momentInSeconds.asHours().toString().padStart(2, '0') : momentInSeconds.asHours().toString();
if (!Number.isInteger(Number(hours))) hours = '0'+ Math.floor(hours);
const minutes = momentInSeconds.minutes().toString().length < 2
? momentInSeconds.minutes().toString().padEnd(2, '0') : momentInSeconds.minutes().toString();
const absolute = hours + minutes;
return absolute;
;
console.log(parseIsoToAbsolute('PT1H30M'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
【讨论】:
如果您将代码作为 sn-p 插入,您将能够测试该方法并向控制台显示一些输出。 没问题!刚刚更新了 sn-p 以进行快速测试。【参考方案29】:只有 moment.js 没有任何其他插件
moment().startOf('day').seconds(duration).format('HH:mm:ss')
【讨论】:
【参考方案30】:如果您使用 Angular >2,我制作了一个受 @hai-alaluf 答案启发的管道。
import Pipe, PipeTransform from "@angular/core";
@Pipe(
name: "duration",
)
export class DurationPipe implements PipeTransform
public transform(value: any, args?: any): any
// secs to ms
value = value * 1000;
const days = Math.floor(value / 86400000);
value = value % 86400000;
const hours = Math.floor(value / 3600000);
value = value % 3600000;
const minutes = Math.floor(value / 60000);
value = value % 60000;
const seconds = Math.floor(value / 1000);
return (days ? days + " days " : "") +
(hours ? hours + " hours " : "") +
(minutes ? minutes + " minutes " : "") +
(seconds ? seconds + " seconds " : "") +
(!days && !hours && !minutes && !seconds ? 0 : "");
【讨论】:
以上是关于如何在 moment.js 持续时间内使用 format()?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Vue 模板内的 Moment.js 格式化程序上转义 HTML 字符串?
使用 Rollup for Angular 2 的 AoT 编译器并导入 Moment.js