amTimeAgo Filter Calculate months wrong

344 views Asked by At

I'm working with angular-moment library. For some reason It treats anything over 25 days as a month when using amTimeAgo.

In this example I'm using moment JS to count back 25, 26, 27 days from current time. Then using the amTimeAgo to calculate the duration from now.

angular.module('timeApp', ['angularMoment'])
.controller('mainController', [ '$scope', function($scope) {
  
   $scope.today = new Date();
   $scope.parsedToday = moment($scope.today).format('MM/DD/YYYY hh:mm A');
   $scope.days25FromNow = moment($scope.today).subtract({days: 25}).format('MM/DD/YYYY hh:mm A');
   $scope.days26FromNow = moment($scope.today).subtract({days: 26}).format('MM/DD/YYYY hh:mm A');
   $scope.days27FromNow = moment($scope.today).subtract({days: 27}).format('MM/DD/YYYY hh:mm A');
  
}]);
<!DOCTYPE html>
<html>

  <head>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.16.0/moment.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular-moment/1.0.0/angular-moment.min.js"></script>

    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>
  
  <body>
    <div class="container" ng-app="timeApp" ng-controller="mainController as main">

      <div>
        <h2>AmTimeAgo Error in Over 25 days</h2>
        <h3>The Time is {{ parsedToday}}</h3>
        
        <p>25 Days From Now - {{days25FromNow}} <br>
          Original AM Time Ago -  {{days25FromNow | amTimeAgo}} <br>
          Expect - 25 days ago
        </p>

        <p>26 Days From Now - {{days26FromNow}} <br>
          Original AM Time Ago -  {{days26FromNow | amTimeAgo}}<br>
          Expect - 26 days ago
        </p>
        
        <p>27 Days From Now - {{days27FromNow}} <br>
          Original AM Time Ago -  {{days27FromNow | amTimeAgo}}<br>
          Expect - 27 days ago
        </p>        
      </div>
      
      
    </div>
  </body>

</html>

Same Example in Plnkr - http://plnkr.co/edit/DZqqI5BC2XNrITThLCS7?p=preview

Is there a configuration that I can set so it calculate to 30 days as a month? or is a this bug? I'm going through their docs and source, I can't seems to find where to change this to 30 days.

Thanks!

1

There are 1 answers

1
Matt Johnson-Pint On BEST ANSWER

You have a bigger concern. You'll notice your code is generating the following warning in the snippet here, and in the debug console in your Plunker example.

Deprecation warning: value provided is not in a recognized ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.

Whatever you are passing as input to the amTimeAgo filter is going to become an argument to the moment(...) factory function. Therefore, you should not be formatting it with a locale-specific format.

Simply remove the .format('MM/DD/YYYY hh:mm A') from your daysXXFromNow fields and it will render correctly, as it will pass a moment object in, which is perfectly acceptable.

To answer the question you asked, you are seeing the correct behavior, as there are relative thresholds to consider. By default, a period of 26 to 45 days is considered a month. This is described here.

You can customize these settings as desired, by setting the relative time thresholds, as described here.

For example, say you wanted to increase the one-month threshold to 28 days, you'd call:

moment.relativeTimeThreshold('d', 28);

Keep in mind that the term "months" is relatively difficult to define with precision in the first place (since every month has a different number of days), and also that the fromNow is intentionally approximate.

If instead you just wanted the number of days exactly, you'd use the diff function instead of the fromNow function.