How can I humanize this full duration in moment.js / javascript

I have a time counter left to upload files. The remaining duration is calculated and converted to milliseconds as follows:

var elapsedTime = e.timeStamp - timestarted; var speed = e.loaded / elapsedTime; var estimatedTotalTime = e.totalSize / speed; var timeLeftInSeconds = (estimatedTotalTime - elapsedTime) / 1000; 

Then I create an array, which I am going to build in a humanized string. The array is as follows:

 var time = { years : Math.round(moment.duration(timeLeftInSeconds, 'milliseconds').years()), months : Math.round(moment.duration(timeLeftInSeconds, 'milliseconds').months()), days : Math.round(moment.duration(timeLeftInSeconds, 'milliseconds').days()), hours : Math.round(moment.duration(timeLeftInSeconds, 'milliseconds').hours()), minutes : Math.round(moment.duration(timeLeftInSeconds, 'milliseconds').minutes()), seconds : Math.round(moment.duration(timeLeftInSeconds, 'milliseconds').seconds()) }; 

All this works fine, and if I output a string representation of this data like this:

  console.log(time.years + ' years, ' + time.months + ' months, ' + time.days + ' days, ' + time.hours + ' hours, '+ time.minutes + ' minutes, ' + time.seconds + ' seconds'); 

I return a nice simple stream of remaining time:

 0 years, 0 months, 0 days, 0 hours, 1 minutes, 7 seconds 

What I now need to do is to humanize this conclusion so that the line is constructed depending on the remaining time. eg

  • 2 years and 3 months left
  • 1 hour, 32 minutes and 41 seconds remaining
  • 7 seconds left
  • 3 minutes remaining: 46 seconds remaining
  • 6 seconds left

etc ... etc ...

Now I know that moment.js has the ability to automatically characterize a duration that works fine for single values, but it can have several possible values ​​(hours / minutes / seconds, etc.)

How can I characterize this data using either moment.js or manually creating a string?

Thanks in advance.

+8
javascript momentjs
source share
3 answers

I think your best bet would be something like this:

 function humanize(time){ if(time.years > 0){ return time.years + ' years and ' + time.months + ' months remaining';} if(time.months > 0){ return time.months + ' months and ' + time.days + ' days remaining';} if(time.days > 0){ return time.days + ' days and ' + time.hours + ' hours remaining';} if(time.hours > 0){ return time.hours + ' hours and ' + time.minutes + ' minutes and ' + time.seconds + ' seconds remaining';} if(time.minutes > 0){ return time.minutes + ' minutes and ' + time.seconds + ' seconds remaining';} if(time.seconds > 0){ return time.seconds + ' seconds remaining';} return "Time up!"; } 

Alternatively, you can use this function:

 function humanize(time){ var o = ''; for(key in time){ if(time[key] > 0){ if(o === ''){ o += time[key] + ' ' + key + ' '; }else{ return o + 'and ' + time[key] + ' ' + key + ' remaining'; } } } return o + 'remaining'; } 

It returns "x <time> and y <time> remaining" for the two largest values. (Or just seconds in the latter case.

+7
source share

My HumanizeDuration.js library sounds exactly the way you want:

 humanizeDuration(1); // "1 millisecond" humanizeDuration(3000); // "3 seconds" humanizeDuration(2012); // "2 seconds, 12 milliseconds" humanizeDuration(97320000); // "1 day, 3 hours, 2 minutes" 

It seems like my answer is a bit late, but maybe this will help others to take a look at this question!

+9
source share

You should try this plugin: moment-duration-format

Its syntax is very convenient:

 var moment = require('moment'); require("moment-duration-format"); moment.duration(32832, "seconds").format("h [hrs]: m [min]: s [sec]") // => 9 hrs: 7 min: 12 sec" 
+2
source share

All Articles