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!
431 Answers
// 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); 11convert duration to ms and then to moment:
moment.utc(duration.as('milliseconds')).format('HH:mm:ss') 2We are looking into adding some kind of formatting to durations in moment.js. See
A couple other libraries that might help out are and
8Use this plugin Moment Duration Format.
Example:
moment.duration(123, "minutes").format("h:mm"); 4Use this line of code:
moment.utc(moment.duration(4500, "seconds").asMilliseconds()).format("HH:mm:ss") 3var diff = moment(end).unix() - moment(start).unix(); moment.utc(moment.duration(diff).asMilliseconds()).format("HH:mm:ss.SSS"); 5The 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.
0You don't need .format. Use durations like this:
const duration = moment.duration(83, 'seconds'); console.log(duration.minutes() + ':' +duration.seconds()); // output: 1:23 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 6I use:
var duration = moment.duration("09:30"); var str = moment(duration._data).format("HH:mm"); And I get "09:30" in var str.
5I 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. ;)
1if diff is a moment
var diff = moment(20111031) - moment(20111010); var formated1 = moment(diff).format("hh:mm:ss"); console.log("format 1: "+formated1); 6If 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' 1If 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') 2Based 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 4I 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
0To 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> 1My 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:
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, '') 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>2If 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 : ""); } } 