Moment: Parse value without fallback

Created on 10 Jul 2015  ·  9Comments  ·  Source: moment/moment

Passing an arbitrary value to moment(value) produces a deprecation warning as per #1407.

It would be really nice if there was some way to use this parsing but without falling back to the Date constructor. The only way I have found so far is fairly clumsy:

if (moment.isDate(value)) {
    return moment(value);
} else {
    return moment(value, moment.ISO_8601);
}

And even then this still doesn't parse ASP.net /Date(1198908717056)/ strings.

The simplest option would be to allow the strict option in two-argument form: moment(value, true).

Thanks.

Enhancement

Most helpful comment

@SystemParadox in case it's helpful, I had a similar issue to yours and I wound up creating wrapper functions like this:

function disableNativeDateFallback(config) {
    config._d = new Date(parseFloat('NaN')); // an invalid date
}
function makeMomentWrapper(momentFn) {
    return function() {
        var prevFallback = moment.createFromInputFallback;
        moment.createFromInputFallback = disableNativeDateFallback;
        var result = momentFn.apply(null, arguments);
        moment.createFromInputFallback = prevFallback;
        return result;
    }
};
var momentStrict = makeMomentWrapper(moment);
momentStrict.utc = makeMomentWrapper(moment.utc);

They work by replacing createFromInputFallback briefly and then restoring it before they return to avoid affecting other code. Any code you're ready to migrate can use momentStrict and momentStrict.utc instead of moment and moment.utc and the rest can stay the way it is.

All 9 comments

Just to clarify, you're asking for a way to disable to fall-back rather than show the warning - without using strict mode, right?

Yes I want to automatically parse all the things that moment() supports, but if they all fail, instead of printing a warning and using the Date constructor, I want it to produce an invalid date.

I want to preemptively opt-in to the behaviour of a future version of moment, where the deprecated Date constructor fallback will removed entirely.

I'm not sure exactly what you mean by strict mode. Do you mean when passing the exact format like moment(value, 'YYYY-MM-DD')? If so, this doesn't help because 1. it's prohibitively verbose and 2. it still doesn't include all the formats that moment(value) can parse before it resorts to the Date constructor.

Strict mode is enabled by passing true as the last parameter. It's in the docs. Basically, it means that the string must match the format _exactly_.

Since the formats supported directly by moment(String) are listed in the docs, I think it would be acceptable to consider this the same as strict mode. In other words, adding moment(String, Boolean).

Yes that would be great. Thanks.

@SystemParadox yes, what you want IS supported. You just override moment.createFromInputFallback(config):

moment.createFromInputFallback = function (config) {
    config._d = new Date(NaN);
}

I agree it is not trivial, but it is possible ;-)

That's helpful, but changes the setting globally.

What if I want to progressively migrate a codebase one call at a time?

Why can we not just add support for moment(String, true)?

Reopening, while there is the workaround, having this in the public API would help a variety of use cases. Consider also #2535, asking for validation around just the build-in formats.

What is needed is the moment.JS_DATE constant, that means just pass the input to new Date, check https://github.com/moment/moment/issues/1686. Accepting pull requests.

@SystemParadox in case it's helpful, I had a similar issue to yours and I wound up creating wrapper functions like this:

function disableNativeDateFallback(config) {
    config._d = new Date(parseFloat('NaN')); // an invalid date
}
function makeMomentWrapper(momentFn) {
    return function() {
        var prevFallback = moment.createFromInputFallback;
        moment.createFromInputFallback = disableNativeDateFallback;
        var result = momentFn.apply(null, arguments);
        moment.createFromInputFallback = prevFallback;
        return result;
    }
};
var momentStrict = makeMomentWrapper(moment);
momentStrict.utc = makeMomentWrapper(moment.utc);

They work by replacing createFromInputFallback briefly and then restoring it before they return to avoid affecting other code. Any code you're ready to migrate can use momentStrict and momentStrict.utc instead of moment and moment.utc and the rest can stay the way it is.

Was this page helpful?
0 / 5 - 0 ratings