0

One of the charms of the moment.js library is the perfect way it deals with sometimes having 366 days in a year ;-) and the varying length of monthes.

So I have assembled the following piece of code:

<script src='https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.3/moment.js' type='text/javascript'></script>
<script type="text/javascript">

Date.getFormattedDateDiff = function(date1, date2) {
  var b = moment(date1),
      a = moment(date2),
      intervals = ['years','months','weeks','days','hours','minutes','seconds'],
      out = [];

  for(var i=0; i<intervals.length; i++){
      var diff = a.diff(b, intervals[i]);
      b.add(diff, intervals[i]);
      out.push('<div>' + diff + ' ' + intervals[i] + '</div><br/>');
  }
  return out.join(' ');
};

window.onload = function calculateInterval() {
   var start = moment("2013-09-04"),
       end   = moment();

   document.getElementById('output').innerHTML  
     = 'Time elapsed between "' + start.toISOString().split('T')[0]
     + '" and "' + end.toISOString().split('T')[0] + '":<br/><br/>' 
     + Date.getFormattedDateDiff(start, end);
}
</script>

<p><label id="output"></label></p>

A codepen can be found here ...

Probably you will immediately notice that I am missing the leading zeros in the result. I have tried several formatting-efforts. But unfortunately, all of them don't seem to work.

Any suggestions how to get the leading zeros in the result, so 07 years instead of 7 years, etc. are highly appreciated.

Piotr Linski
  • 83
  • 1
  • 12

2 Answers2

2

In your case you should handle it manually, because you output raw numbers. One way to do this is to use method padStart

diff.toString().padStart(2, '0')

But this won't work in older browsers, see https://caniuse.com/?search=padStart for browser support.

You could write something like this instead

function getLeadingZeroNum(num) {
    return num < 10 ? '0' + num : num;
}

getLeadingZeroNum(4) // 04;
t1m0n
  • 3,413
  • 1
  • 17
  • 21
1

Simple if statement to prepend a 0 will work -- typeof diff() value returns number and you need to convert to a string to manipulate.

Date.getFormattedDateDiff = function(date1, date2) {
  var b = moment(date1),
      a = moment(date2),
      intervals = ['years','months','weeks','days','hours','minutes','seconds'],
      out = [];

  for(var i=0; i<intervals.length; i++){
      var diff = a.diff(b, intervals[i]);
      b.add(diff, intervals[i]);
      if (diff.toString().length == 1) {
        diff = "0" + diff.toString();
      }
      out.push('<div>' + diff + ' ' + intervals[i] + '</div><br/>');
  }
  return out.join(' ');
};

window.onload = function calculateInterval() {
   var start = moment("2013-09-04"),
       end   = moment();

   document.getElementById('output').innerHTML  
     = 'Time elapsed between "' + start.toISOString().split('T')[0]
     + '" and "' + end.toISOString().split('T')[0] + '":<br/><br/>' 
     + Date.getFormattedDateDiff(start, end);
}

You can also refer to this thread for some fantastic leading 0 methods.

franklylately
  • 1,112
  • 10
  • 12
  • Initially I was looking for a solution that makes use of something like moment(Date).format('MM/DD/YYYY'). However, your pragmatic solution works perfectly. So it's fine with me. Thanks a lot! – Piotr Linski Mar 08 '21 at 07:53
  • Unfortunately `moment(end).diff(start)` outputs the unix milliseconds as a number. `moment(value).format("YY-MM-DD HH:mm:ss")` formats it correctly to what you're looking for, but assumes you're entering a raw date in milliseconds and goes to (19)77-07-05 05:09:30 though my .format input is probably wrong – franklylately Mar 08 '21 at 15:13