Matheno
Matheno

Reputation: 4152

Bug in Moment.js?

I'm facing an issue which I just can't solve. In AngularJS I created a directive that checks the validity of a date. For this I use Moment.js

This is my directive:

/* @ngInject */
function modelDate() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, ngModel) {
            var validate = function (value) {
                if (!value) {
                    // don't validate an undefined value. required or ng-required should handle that
                    ngModel.$setValidity('date', true);
                    ngModel.$setValidity('maxDate', true);
                    ngModel.$setValidity('minDate', true);
                    return value;
                }

                var date = moment(value, ['DD-MM-YY', 'DD-MM-YYYY', 'DD-MM']);
                if (!date.isValid()) {
                    // invalid date, so no validity check on max and min date
                    ngModel.$setValidity('date', false);
                    ngModel.$setValidity('maxDate', true);
                    ngModel.$setValidity('minDate', true);
                    return value;
                } else {
                    ngModel.$setValidity('date', true);
                }

                if (ngModel.$viewValue !== date.format('DD-MM-YYYY')) {
                    // format and set value
                    value = date.format('DD-MM-YYYY');
                    element.val(value);
                }

                return value;
            };

            ngModel.$parsers.push(validate); // for DOM -> model validation
            ngModel.$formatters.push(validate); // for model -> DOM validation
        }
    };

My issue is the following:

When I enter the date 29-02-2015, moment(value, ['DD-MM-YY', 'DD-MM-YYYY', 'DD-MM']) returns me 29-02-2020. While I expect an invalid date. This is also for 2001, 2002 etc. Basically every none leap year from 2001 till now.

Did someone faced this issue before?

I created a small fiddle to demonstrate the issue: http://jsfiddle.net/r42jg/1183/

Upvotes: 2

Views: 743

Answers (3)

Robbert Draaisma
Robbert Draaisma

Reputation: 463

I think this is not a bug.

From the docs:

So the first format 'DD-MM-YY' produces a valid date.

Upvotes: 1

Tom
Tom

Reputation: 2631

It looks to be due to you passing an array of formats to moment. As far as I can tell, moment doesn't support accepting an array of formats, only a format string.

See http://momentjs.com/docs/#/parsing/string-format/

If you change the format to just a string, then you will get the expected behaviour: http://jsfiddle.net/wc9bstux/

So change: moment(value, ['DD-MM-YY', 'DD-MM-YYYY', 'DD-MM']) to be moment(value,'DD-MM-YYYY').

Upvotes: -1

Fredrik Holm
Fredrik Holm

Reputation: 166

Just a reflection: I used moment.js for general date validity checks a while back, and I also noticed that it can be very forgiving.

What I did was to compare the input with the result; if they don't match, the date is invalid.

That of course assumes that the format of the input date is known.

Upvotes: 1

Related Questions