How to use format() on a moment.js duration?

Is there any way I can use the moment.js format method on duration objects? I can't find it anywhere in the docs and it doesn't seen to be an attribute on duration objects.

I'd like to be able to do something like:

var diff = moment(end).unix() - moment(start).unix(); moment.duration(diff).format('hh:mm:ss') 

Also, if there are any other libraries which can easily accommodate this sort of functionality, I'd be interested in recommendations.

Thanks!

4

31 Answers

1 2

// 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

11

convert duration to ms and then to moment:

moment.utc(duration.as('milliseconds')).format('HH:mm:ss') 
2

We are looking into adding some kind of formatting to durations in moment.js. See

A couple other libraries that might help out are and

8

Use this plugin Moment Duration Format.

Example:

moment.duration(123, "minutes").format("h:mm"); 
4

Use this line of code:

moment.utc(moment.duration(4500, "seconds").asMilliseconds()).format("HH:mm:ss") 
3
var diff = moment(end).unix() - moment(start).unix(); moment.utc(moment.duration(diff).asMilliseconds()).format("HH:mm:ss.SSS"); 
5

The best scenario for my particular use case was:

var duration = moment.duration("09:30"), formatted = moment.utc(duration.asMilliseconds()).format("HH:mm"); 

This improves upon @Wilson's answer since it does not access private internal property _data.

0

You don't need .format. Use durations like this:

const duration = moment.duration(83, 'seconds'); console.log(duration.minutes() + ':' +duration.seconds()); // output: 1:23 

I found this solution here:

EDIT:

And with padding for seconds, minutes and hours:

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 
6

I use:

var duration = moment.duration("09:30"); var str = moment(duration._data).format("HH:mm"); 

And I get "09:30" in var str.

5

I needed to do this for work as a requirement to display the hours in this format. At first I tried this.

moment.utc(totalMilliseconds).format("HH:mm:ss") 

However anything over 24 hours and the hours reset to 0. But the minutes and seconds were accurate. So I used only that part for the minutes and seconds.

var minutesSeconds = moment.utc(totalMilliseconds).format("mm:ss") 

Now all I need is the total hours.

var hours = moment.duration(totalMilliseconds).asHours().toFixed() 

And to get that format that we all want we just glue it together.

var formatted = hours + ":" + minutesSeconds 

if totalMilliseconds is 894600000 this will return 249:30:00.

Hope that helped. Leave any questions in the comments. ;)

1

if diff is a moment

var diff = moment(20111031) - moment(20111010); var formated1 = moment(diff).format("hh:mm:ss"); console.log("format 1: "+formated1); 
6

If you're willing to use a different javascript library, numeral.js can format seconds as follows (example is for 1000 seconds):

var string = numeral(1000).format('00:00'); // '00:16:40' 
1

If all hours must be displayed (more than 24) and if '0' before hours is not necessary, then formatting can be done with a short line of code:

Math.floor(duration.as('h')) + moment.utc(duration.as('ms')).format(':mm:ss') 
2

Based on 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 
4

I use the classic format function in these cases:

var diff = moment(end).unix() - moment(start).unix(); //use unix function instead of difference moment.unix(diff).format('hh:mm:ss') 

This is a hack because the time diff is treated as a standard moment date, an early epoch date time, but it doesn't matter to our goal and you don't need any plugin

0

To format moment duration to string

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

if you use angular add this to your filters:

.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 ': '') } }) 

usage example

<div> {{diff | durationFormat}} </div> 
1

My solution that does not involve any other library and it works with 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)) 

Short version (one-liner):

moment.duration(durationInMs).asHours()|0||"00" + ":" + moment.utc(durationInMs).format("mm:ss") 

Extended version:

export const formatDuration = (durationInMs) => { const hours = Math.floor(moment.duration(durationInMs).asHours()) || "00" return hours + ":" + moment.utc(durationInMs).format("mm:ss") } 

Example cases:

Example cases

How about native 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; } 

moment.duration(x).format() has been deprecated. You can usemoment.utc(4366589).format("HH:mm:ss") to get the desired response.

console.log(moment.utc(4366589).format("HH:mm:ss"))
<script src=""></script> <script src=""></script>

How to correctly use moment.js durations? | Use moment.duration() in code

First you need to import moment and moment-duration-format.

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

Then, use duration function. Let us apply the above example: 28800 = 8 am.

moment.duration(28800, "seconds").format("h:mm a"); 

🎉Well, you do not have above type error. 🤔Do you get a right value 8:00 am ? No…, the value you get is 8:00 a. Moment.js format is not working as it is supposed to.

💡The solution is to transform seconds to milliseconds and use UTC time.

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

All right we get 8:00 am now. If you want 8 am instead of 8:00 am for integral time, we need to do RegExp

const time = moment.utc(moment.duration(value, 'seconds').asMilliseconds()).format('h:mm a'); time.replace(/:00/g, '') 

Use moment-duration-format.

Client Framework (ex: React)

import moment from 'moment'; import momentDurationFormatSetup from 'moment-duration-format'; momentDurationFormatSetup(moment); const breakLengthInMinutes = moment.duration(breakLengthInSeconds, 's').format('m'); 

Server (node.js)

const moment = require("moment-timezone"); const momentDurationFormatSetup = require("moment-duration-format"); momentDurationFormatSetup(moment); const breakLengthInMinutes = moment.duration(breakLengthInSeconds, 's').format('m'); 

There is no longer (if there ever was) any need to convert duration to utc to solve this issue. This is like converting a base10 "1" to binary and then saying that since output "1" looks like base10 we'll have no issues assuming this is a base10 value for any further operations.

Use moment-duration-format and note that with { trim: false } you can prevent trimming:

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" 

Let's compare this with the not recommended method of using abusing utc:

moment.utc(moment.duration(1000000, "seconds").asMilliseconds()).format('HH:mm:ss') > "13:46:40" 

Just moment.js without any other plugins

moment().startOf('day').seconds(duration).format('HH:mm:ss') 
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}`); 

Prints:

2 days 14 h 00 min 00 s

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 

You can use numeral.js to format your duration:

numeral(your_duration.asSeconds()).format('00:00:00') // result: hh:mm:ss 

This can be used to get the first two characters as hours and last two as minutes. Same logic may be applied to seconds.

/** * 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=""></script> <script src=""></script> <script src=""></script>
2

If you use Angular >2, I made a Pipe inspired by @hai-alaluf answer.

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

1 2

You Might Also Like