moment / moment

Parse, validate, manipulate, and display dates in javascript.

Home Page:momentjs.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Be careful when falling back to Date constructor

ichernev opened this issue · comments

If you clicked on the warning link and landed here:

moment construction using a non-iso string is deprecated. What this means is you can safely do

> moment("2014-04-25T01:32:21.196Z");  // iso string, utc timezone
> moment("2014-04-25T01:32:21.196+0600");  // iso string with timezone
> moment("2014 04 25", "YYYY MM DD"); // string with format

but you can't do reliably (therefore its being deprecated)

> moment("2014/04/25");
> moment("Thu Apr 24 2014 12:32:21 GMT-0700 (PDT)");
> moment("some random string that looks like date");

In the upcoming releases a few more well defined formats might be added, but the general idea of using any random string to construct a date is no more. If you really want that behavior just do moment(new Date("random string that contains date")), but moment won't be responsible for such convertions. Read below for the rationale about the change

As described in #1403 (comment), but also recent debugging c4d9f6e and 94d6c90 caused by https://travis-ci.org/moment/moment/builds/16672288 brings me to the conclusion that

using Date to create a moment from string, passed from the user is extremely unpredictable, and it turns out to work somewhat and then bite you in an edge case when you're not careful

So I think we need an option to disable it, for tests at the very least. I've debugged that numerous times thank to our old friend IE6 and friends.

You'd pass a string only, hoping that it would hit one of the predefined formats, but instead it hits Date and it sort-of works, sometimes. I think it should be clear to users when they're hitting this case, and that it might not work well on all browsers.

The only use-case for using Date to parse input is when a) it is entered by a web user (moment's user's user :)) and b) the web user can see how we're interpreting the date entered. Every other case is just silently waiting to break at some point.

+1. I totally agree. We should start issuing a deprecation warning right away. Some additional support:

  • That a string might go into the Date constructor or the ISO parser is ugly and confusing
  • The most reliable way of using the Date string constructor was always new Date('2014-01-01'), which is now handled by the ISO parser anyway (i.e. moment('2014-01-01') doesn't use the Date constructor anyway).
  • I'm pretty sure the constructor works differently in different locales for the same browser. E.g. new Date("05/06/2014") is May 6 in American browsers but June 5 in English browsers. So even if you test all your browsers, did you test all your locales? It's terrible for us to even pretend this stuff works.
  • If you really want to use the date constructor, you can always just use the date constructor and pass the date into Moment.
  • We could make moment(string) extensible, and then someone could create a plugin that either uses a list of well-known formats or just the Date constructor to parse them.
  • If we remove the Date constructor fall-back, we can actually make the ISO parser less strict, since it won't be preempting a better parse. So that's a win too.

The idea I liked most is for extensible constructor -- even if we disable Date parsing in moment, we should make it easy for people to migrate.

So lets do this:

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

And call this method in the else clause of makeDateFromInput. In 3.0 we'll just remove this function, or place it under another name, so that one can just assign to the preset.

For tests right now, we can put a different function that throws an exception if called. I hope that would work just fine.

Inside we can print using console.warn (would go to stderr in node), only the first time it is called (like global deprecation) -- this is to let users know what awaits them.

I don't understand this deprecation warning. I am using moment.js as documented, in an Angular.JS filter:

app.filter('scanDate', function() {
    return function(input) {
        var m = moment(input);
        return m.format("dddd, MMMM Do YYYY");
    };
});

Where input is an ISO formatted date string.

What do I need to do different to deal with this future deprecation?

If this deprecation warning is for the developers of this library and not for the users of it then I am going to suggest to remove it.

@st3fan Are you sure it's an ISO-formatted string? Moment is claiming that it isn't; it's saying that it can't parse it, and it is instead resorting to passing the string to new Date(s), which happens to work. That's the feature we're removing and are warning you about. In the future, it will fail. Your options are:

  1. Ensure that the input really is ISO-8601 compliant (and file a bug if you think it is but are getting the warning anyway)
  2. Parse the input explicitly using moment(input, string)

The warning is very much for you :)

This is implemented, so I'm closing it.

If we deprecate everything in Javascript that doesn't work on a side-case there will be no features left. ;) Looking forward to at least a few other "sane" date formats being added back in. Explicitly creating a Date or including the format string removes a lot of Moment's elegance.

@Meekohi We'll always allow ISO strings like '2013-05-10', which IMO everyone should just use. As for other strings, '05/10/2013' works differently in different locales, and most of the rest don't work across browsers. These aren't really side-cases; we receive an awful lot of support tickets here about surprises from things like moment("1.10.2014") where the user is expecting us to parse it consistently.

We are allowing this to be pluggable, so you can override the fallback parser (i.e. the thing currently giving a deprecation warning and then using the native parser) to do anything you'd like, and I suspect there will be some plugins built that do just that.

@icambron Is the correct way to plugin your own parser to overwrite createFromInputFallback? i.e.

moment.createFromInputFallback = function(config) {
  // unreliable string magic, or
  config._d = new Date(config._i);
};

hi guys,
i'm use moment on my node apps.
i using it something like this one

moment(Date('2014-04-21T05:29:59Z')).format("DD-MM-YYYY")

now when i check log on my server, i get error message on my log files

Deprecation warning: moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.

@Aredo I think you're expecting Date(string) to return a Date? It appears to return a string. I think you want moment(new Date(string)) or moment(Date.parse(string)), or even just moment('2014-04-21T05:29:59Z')

I'm using an iso 8601 format like this: 2014-04-29 17:47:12, is there a list of the supported formats that will not be deprecated?

(Editing because I misunderstood the question and this is kind of an important doc now). @godoploid Only ISO 8601 are asp.net-JSON-style dates are not deprecated. On your specific format, that isn't ISO-compliant. Use a "T" instead of a space, as in "2014-04-29T17:47:12" (see here).

@icambron Got it thanks, I'll make sure to do so!

@icambron
But how I format the current time?

When i try this var now = moment().format('YYYY-M-D'), it warning me: moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.

@imsobear I'm not sure the error message you see is from moment().format('YYYY-M-D'), I think its something before that.

The documentation have a example that throws this Deprecation message.

Yeah I know, there is "warning" text, but if is for remove, maybe some "Deprecation" in the docs, could help the newbies.

moment("Dec 25, 1995")  -> "moment construction falls..."

http://momentjs.com/docs/#/parsing/string/

Hello nice folks. I came here via the deprecation link and am totally fine with having moment not try to parse garbage. I found this while writing a test to make my code check for .isValid().

What is the recommended way of disabling this warning?

Ugh. Postgresql native date types are no longer supported because of this?

@matthew-dean && @elliotf ,

moment.createFromInputFallback = function(config) {
  // unreliable string magic, or
  config._d = new Date(config._i);
}; 

via @Meekohi's comment is how to put the old behavior back in for now.

@matthew-dean can you please be more specific? What date format do you want parsed? Also if you know that this comes from postgresql I'd really suggest writing a proper format and using it when you want to parse it. This approach is far superior, and this is why we're deprecating the Date fallback in the first place.

Sorry, forgot to update this. Bad form. It was neither Moment nor Postgresql date formats, but the incorrectly-written gist (of someone else) I was basing some code on that used the two.

Sorry if I have miss understood something here but I just want to be clear on how isValid() is working.

Current version moment('2014 05 12').isValid() // true + warning message
Next major version moment('2014 05 12').isValid() // false + no warning message

This correct?

So now moment throws a warning when it tries to parse its own created dates if they're saved to a string?

localStorageService.set('now', moment());
var now = localStorageService.get('now');
moment(now).isValid(); // <-- false? (e.g. "2014-07-22T16:33:18.097Z")

Any ideas?

@jough That's a good point; we ought to be able to parse our own toString format. @ichernev what do you think? We could make toString() just ISO or we could support the format explicitly.

We use Date's toString, we should be able to parse that. Its an rfc I linked in the parsing issue #1686

What about number as string? Shouldn't it be parsed as milliseconds?

@tsouza if you know its a number why don't you convert it first. Storing a numeric timestamp in string doesn't look like something we want to encourage. Just do moment(+string_containing_number).

Well, what about if I don't know if it's a number? One great feature of momentjs is that it can convert anything that is convertable to a date.

I'm getting this deprecation notice too, but I'm never providing a date without an accompanying format string. If it's that the supplied date string doesn't match the format, I would expect a different error, no?

@Synchro correct, you should never get that message if you always include a format string. Can you provide a reproduceable example?

I get this error in our production app but without a line number, it's very hard to pinpoint what exactly generates the error. We use the live-timestamp Meteor package, so maybe that's the culprit, but who knows? Or maybe there's no incorrect usage of non-ISO date formats.

Can moment please complain about specific instances of this deprecated usage?

commented

If you can reproduce the message on your development / testing environment, you can use something like this to temporarily transform console.warn and get the stacktrace of the message :
console.warn = console.trace.bind(console);

Thanks @Y-- - turns out that the livestamp js library has this issue.

@ichernev: shouldn't there be a deprecation warning in the docs at http://momentjs.com/docs/#/parsing/string/?

I agree with @dandv , this should include a file/line number message such as this deprecation warning from express.js:

express deprecated res.json(status, obj): Use res.status(status).json(obj) instead api/controllers/view-controller.js:77:20

In very large complex projects it's hellacious to find where this is coming from otherwise.

@dandv we need to put something there. The problem is we haven't yet figured out how to make the new api in a way that will break the least amount of users, is more flexible and still lets you do the old stuff. The current proposal is: #1686

@WhatFreshHellIsThis we need some call stack hacks to figure that out. It won't work on some restricted environments (browser plugins), so I'm not very excited. I'd merge a PR if it looks solid (shouldn't crash in any case), and is not a lot of code. It might need to traverse the stack until it finds the first non-moment code -- in minified code that is not possible (one issue OTOH).

So why parsing of "Thu Apr 24 2014 12:32:21 GMT-0700 (PDT)" is deprecated? I would love that formats which are non ambiguous are still automatically parsed. Those which are (day/month/year vs. month/day/year) are understandable to have issues and one might not want to parse it automatically (but there could be on option about preference). I am using Moment to parse dates which I get in various formats from external sources and I do not know which all formats they will be in. For non ambiguous formats I would love to get them parsed automatically. For ambiguous formats I should tell which one I prefer. For garbage it should throw an error or something.

👍 to what @mitar just said

@mitar The problem is that that's not actually how Moment works. When it's parsing a string like "Thu Apr 24 2014 12:32:21 GMT-0700 (PDT)", it is just passing that string to the Date constructor and using the date that comes out. There are some formats that work on all browsers, some that work on some browsers but not others, and of course many perfectly unambiguous ones that work on no browsers. Moment doesn't know the difference between those formats. The Moment interface doesn't do a good job of making that clear and that leads to a lot of confusion about what will work where, so we've deprecated it.

See #1686 for the explicit API we plan to implement to make this both clear and convenient. And you can always do moment(new Date(whatever)) if you're confident the string is parsable by the constructor; that's all Moment was doing for non-ISO strings anyway.

OK, but then I must say that I was completely misusing the Moment for all this years. The main reason for me why I was using Moment was because I believed it does a better job than Date. I thought that the main purpose of Moment is to parse such dates. That it tries various formats and that it knows how to parse more than what Date was parsing. Are you sure this was not a feature in the past?

@mitar It tries ISO-8601 explicitly, and if that fails, it falls back on the date constructor. As far as I know, that's always been how it works, and we've long encouraged users to use explicit parsing strings where possible. So your confusion is exactly what we're aiming to fix with this deprecation :)

In reference to what @mitar said above, it would be very nice if moment(moment().toString()) was supported. I'm not sure if this means parsing the JS date format, or changing the toString() of moment, but it would be nice. :)

Well... I suppose moment(moment().toISOString()) isn't a terrible compromise...

@jwalton I generally agree (see my comments higher up in this ticket). We could try the toString format explicitly. If we left the end open, that should also work for new Date().toString() (i.e. the string used by @mitar). The native date toString() format is actually not defined by the spec but it will mostly OK in practice if we ignore the TZ abbreviation at the end. It's a bit more complicated than that because of localization, but it's likely that something could be made to work.

Hi, I use the following node.js code to query a MongoDB database for two documents. One at the start of day (time lies in the first 10 seconds of the day) and a second document at the end of the day (time lies in the last 10 seconds of the day). The code works ok but I get a deprecated warning.
The code is:
var query = { $or: [ { date: new RegExp(moment(date).format("YYYY-MM-DDT00:00:0")) }, { date: new RegExp(moment(date).format("YYYY-MM-DDT23:59:0")) } ] };
Where date is a string containing "2014-9-30".

The result is a query object containing:
{ '$or':
[ { date: /2014-09-30T00:00:0/ },
{ date: /2014-09-30T23:59:0/ } ] }

How would the new syntax look like?

Thanks,
Jacco

commented

How can I find what line of code is causing the warring message to be thrown? (sorry if noob question). I'm using Firebug to see and try to debug my code. I believe its being thrown by one of the 3rd party plugins that relies on moment that i'm using, but can't seem to narrow it down (too hard to disable all but 1 plugin).
Thanks,

@marc-gist You could try setting a breakpoint in Firebug in the function that logs deprecation warnings and then look at the call stack.

I don't understand why this issue is closed? The problem is neither solved, nor I found anything in the documentation about this problem. Just a console.log with a warning and only for the first execution.

BTW: is there a release date for moment 3?

There should be a note in the docs: http://momentjs.com/docs/#/parsing/utc/ and http://momentjs.com/timezone/docs/#/using-timezones/parsing-in-zone/ what to avoid, for instance, pass a formatter for non ISO pattern.

commented

These are valid ISO8601 dates that give a deprecated warning:

YYYY    : moment('2014') // year
YYYY-MM : moment('2014-10') // year, month
YYYYMMDD: moment('20141023') // hyphens are supposed to be optional
HHMMSS  : moment('2014-10-23T071823') // colons are supposed to be optional

This incorrectly returns false:

moment('2014-10-23', moment.ISO_8601, true).isValid() // if you add a "T" after the day, it returns true

These work correctly:

moment('2014-10-23') // date

// just hour
moment('2014-10-23T07') // date, hour
moment('2014-10-23T07+01:00') // date, hour, utc offset
moment('2014-10-23T07Z') // date, hour, 0 utc offset shortcut

// just hour, minutes
moment('2014-10-23T07:59') // date, hour, minute
moment('2014-10-23T07:59+01:00') // date, hour, minute, utc offset

// hour, minutes, seconds
moment('2014-10-23T07:59:58') // date, hour, minute, seconds
moment('2014-10-23T07:59:58+01:00') // date, hour, minute, seconds, utc offset

// hour, minutes, seconds, hundredth of a second
moment('2014-10-23T07:59:58.99') // date, hour, minute, seconds, seconds decimal
moment('2014-10-23T07:59:58.99+01:00') // date, hour, minute, seconds, seconds decimal, utc offset

With regards to colons in times being optional, wikipedia:

The basic format is [hh][mm][ss]...so a time might appear as either "134730" in the basic format or "13:47:30" in the extended format.

The documentation makes no mention of this deprecation – it still merrily tells you to construct with a String and such.

This change basically replaces (a) moment(str, moment.ISO_8601); with moment(str) and (b) moment(str) with moment(new Date(str)).

Wouldn't it be easier for everybody to change (a) to moment(str,'iso') or moment(str,true), and get reliable ISO parsing with less typing, without breaking lots of existing software and adding extra typing for people who need (b)?

Is there any way I can get isValid() to return FALSE in v2.8.3 i.e. get this functionality before the next release?

This is really crappy now. Honestly, the entire point of using moment is so that I don't have to think about date formats; with moment they should just work. This deprecation makes me not want to use the library at all, because now I have to think about date formats again and wrap custom (read: hacky) code around my moment instantiations, to do its job for it. A better solution would be to put in more regexes for common date formats that make sense or are obvious. Example: you'll parse "2014-04-29T17:47:12" with a T, but not "2014-04-29 17:47:12" with a space? Seriously?

@soapergem is right. Does Moment want to be once again delightful to use, or not?

I would like to see this issue re-opened, because it seems there's a lot of people still discussing it.

If it's not moment's job to parse random date formats in a browser-compatible manner, what library do I use instead? Datejs? :3

I'm using Moment on Node.js, and I would like the deprecation warning to be removed.

I use Moment to parse user input to get a date, and I don't really care if because of a non-standard string I get a weird result. Next time the user will change his/her input.
In addition to this, on Node.js it should be possible to have less uncertainty on the behaviour as it's not like dealing with dozens of different browsers.

commented

The answer here is pretty clear: someone needs to put together the 50 or so parsing regex's into a lib, that moment could even end up implementing. It seems like a lot of people were mis-using moment, thinking it does more in that department than Date(), which only strengthens the decision to deprecate it (regardless if it was useful for a subset of people).

Can we at least create a moment().unreliable() constructor or anything like that? For some people it doesn't matter if it's not 100% reliable!

I hate to repost this directly, but there is an extremely easy solution for this already posted in this thread:

moment.createFromInputFallback = function(config) {
  // your favorite unreliable string magic, or
  config._d = new Date(config._i);
};

If you have a well defined specific string format you want supported then create a new issue proposing it be supported. If you want to use the Date constructor specifically then do the above.

That is not exactly what I was asking, however. I like the current behaviour, where supported strings are parsed internally and Date() is used for the rest. I don't want to feed everything to Date() either.

@EgoAleSum - as the name createFromInputFallback indicates, moment first checks for an ISO string and will parse it internally, then passes it to the createFromInputFallback function.

I see, thanks

I quite understand moment wanting to avoid being responsible for parsing some random junk format, but my objection to the noisiness of this deprecation is that it also rejects date instances (not strings) created by moment, and date strings that provide an explicit, unambiguous format string (i.e. when no fallback is involved), when the docs say that that is the correct approach.

Actually the black magic parsing is what's most appreciable about moment. I understand the maintainer's logic though... It would be nice if that cruft was moved somewhere else as removing functionality is just not desirable.

Maybe move it to moment-guess, o have a moment.guess() function?

I just wrapped the date inside new Date and then converted to iso string so:

<%= moment(blog_feed[i].publishedDate).format("DD MMM, YYYY") %>

Coverted to:

<%- moment(new Date(blog_feed[i].publishedDate).toISOString()).format("DD MMM, YYYY") %>

Here's a potentially helpful link I haven't seen in any of the issues in this repo:
http://dygraphs.com/date-formats.html (context)

The grid could be updated for newer browsers, though I doubt things have changed much. The most reliable string format for browsers' native Date constructor is of the form "2014/01/23 23:45:01", which will only get you local time. Even the ISO 8601 formats aren't well supported in older browsers, according to the page. (See also issues with Date.parse.)This is why Moment should and will be parsing pretty much everything on its own. For "black magic" stuff and explicit Date constructor fallback, I think #1686 is heading in the right direction (for the most part).

Im using Moment to create a local date from an ISO string. The ISO string is part of an URL and is supposed to look like this: "2014-12-19". An evil user can try to give a bad string like: "20XX-13-19"

Im using the following code in Node to fallback to current date if a bad string is given.

var date = moment(req.params.date).isValid() ? moment(req.params.date).toDate() :  new Date();
// req.params.date is the date part of the url as a string

Will this somehow be broken in a near future because of the deprecation?

I consider moment to be what Date should've been, it is that wonderful. As such, any implementation that requires me to use Date, I would consider broken. Thanks to all those that have mentioned the createFromInputFallback fallback, I guess can handle Date in one place...

commented

Hi,
I'm using the following technique and still get the warning for deprecation.
moment( new Date( date ) ).format( 'MMM D, YYYY' );

Also, when trying:
moment(new Date(date), 'MMM D, YYYY');
I'm getting a "moment object" instead of the returned date.

Anyone knows why?

So If I use the .format option I get the error message but the value that is returned is the date without the timezone but if I use the following moment(this.organicFieldStatusTo, "MM-DD-YYYY", false)

I don't get the error message but the date that is returned has the time how can I remove the time?

What about a case where the user pastes a date string into a text field and one would like to check if the string represents a valid date?

Am I mistaken you can't call isValid() without constructing a moment object that will raise this deprecation warning?

I browsed the whole thread, but nowhere the most common use case is mentioned: Creating a moment with the current date and time.

Since using new Date() is warned about, what's the supported and recommended way to create a moment with the current datetime?

@kashban var now = moment(); will give you a moment object representing the current date/time.

I'm clueless about why am i getting this warning now... i had it fixed but now it's back again...

can anyone guess what's the problem? Here's the code, i'm getting the warning at line "'mild-red-card': (Moment(date... "

getPicClasses: function () {
        var twoWeeks = Moment().subtract(2, 'weeks').format('MM/DD/YYYY');
        var threeWeeks = Moment().subtract(3, 'weeks').format('MM/DD/YYYY');
        var fourWeeks = Moment().subtract(4, 'weeks').format('MM/DD/YYYY');
        var date = this.props.date;

        return cx({
            'pic': true,
            'mild-red-card': (Moment(date, 'MM/DD/YYYY').isBetween(threeWeeks, twoWeeks)) || Moment(date, 'MM/DD/YYYY').isSame(twoWeeks),
            'red-card': (Moment(date, 'MM/DD/YYYY').isBetween(fourWeeks, threeWeeks)) || Moment(date, 'MM/DD/YYYY').isSame(threeWeeks),
            'red-glowing-card': (Moment(date, 'MM/DD/YYYY').isBefore(fourWeeks) ) || Moment(date, 'MM/DD/YYYY').isSame(fourWeeks)
        });
    },

Btw, the date var format is 'MM/DD/YYYY, HH:mm'

Just a thought- what about grabbing a stack trace with new Error() and stuffing it in the deprecation warning? It took me a while to hunt down where this was happening (it was one of our dependencies, https://github.com/urish/angular-moment). I've just started using the same approach in sails/node-machine and it's been pretty effective so far. I'll send a PR- feel free to close or accept, no pressure 👍

@ichernev @icambron here's a link to that: #2175

This is rather confusing. I'm using var now = new Date(); and then now.toString() to put dates into a database, and when I try to read afterwards through moment(item.value.date).format("D MMM YY") I'm getting the deprecation message. Surely moment works with dates created by javascript?

@simonh1000 I am running into a similar issue, using the original suggested solution of parsing my server created strings through a new Date() constructor. I would greatly appreciate @mikermcneil's contribution as it would easily allow me to find where the errors occur.

can you add a stack trace to where the deprecation notice is being called? i can't figure out where it's coming from.

https://github.com/dougwilson/nodejs-depd

Let me hopefully help someone else who is confused (I know it was answered but it wasn't immediately obvious): all you have to do to avoid the deprecation error, having to use new Date & avoiding the unreliability, is to just specify the format of the string that is passed in.

e.g.

moment("2014 04 25", "YYYY MM DD"); // string with format

Yeah, but the ability to make a "best effort" guess in date parsing was
actually really useful.

2015-04-01 19:15 GMT+04:00 rey-wright notifications@github.com:

Let me hopefully help someone else who is confused (I know it was answered
but it wasn't immediately obvious): all you have to do to avoid the
deprecation error, having to use new Date & avoiding the unreliability, is
to just specify the format of the string that is passed in.


Reply to this email directly or view it on GitHub
#1407 (comment).

you can still do that if you use new Date(). They're deprecating it because it's unreliable.

commented

I had been using moment().subtract(1, "day") to get the current date minus one day. Now I am getting the deprecation warning. What is the best way to do this now?

Nevermind...the warning is actually coming from somewhere else.

Issue when using this fix with MomentJs TimeZones

Converting from UTC to an IANATimeZone
moment.utc( 'Apr 8, 2015 4:15 PM' ).tz('Australia/Perth') // Success + Console Error

With Fix
moment.utc( new Date( 'Apr 8, 2015 4:15 PM' )).tz('Australia/Perth') // Failure + No Console Error

The result with the fix just stays in UTC time and does not get converted.

So, just to be clear:

  1. It's not possible to always parse every date like string reliably.
  2. There are dates that work, that sometimes work, and that never work.
  3. Moment doesn't want the blame for dates that sometimes or never work.
  4. Instead of being able to toss warnings on those dates in the future, or to
    explicitly tell moment to do the best it can, e.g., 'moment(something, error:...)' or
    moment(something, guess: true, errror: ...), we tell users to do
    moment(new Date(something)).
  5. This will be much less prone to giving complaints to moment, errors like
    moment(Date(something)) are clearly the users fault, and new versions of JavaScript
    might someday fix the Date function.

Is this the plan?

This does not make any sense. I use the plugin just to not have to parse date, I want him to do it for me. Now I have to parse to the format that the plugin wants to him parse for the format I want? I better make directly to the format I want.

I'm saying exactly the format that the date is:

moment('Thu, 30 Apr 2015 3:01 pm', 'ddd, DD MMM YYYY H:mm a')

Why it can not validate it?

@KaduAmaral You want 'ddd, DD MMM YYYY h:mm a' for your format. Lowercase h, not uppercase H. I assume that's why it's not working for you.

Hi @zackgilbert still not working.

moment('Mon, 04 May 2015 8:01 am', 'ddd, DD MMM YYYY h:mm a').isValid()

The result is false.

Erm, so what about when you are trying to create Moments in UTC using timestamps? How exactly would you pass a format string for a timestamp?
Never mind, apparently it has to be:

var myMoment = moment(timestamp, 'x');

I'm sorry but ugh that kind of defeats the whole purpose of using Moment...
👎

@KaduAmaral
if you look at the parsing/string-format section of the docs, there isn't even a reference to anything that would give you the day name. If you take that portion out of your string and try again, it will probably work:

moment('04 May 2015 8:01 am', 'DD MMM YYYY h:mm a').isvalid()

I have the same question as @Izhaki and @elliotf. How do you check if something is valid without constructing a moment object which gives the warning?
ie. moment("filth").isValid() // gives a warning

I feel like this is a valid use case and don't want to see the warning if there is no problem. Maybe you could argue we should be seeing it since functionality will change at next version, but it will also mask more insidious violations.

This is a confusing error message. I'm sure that the people who put this into my console are very clever and very pleased to demonstrate this to everyone. I'm sorry but I think you've misunderstood why people like me want to use this - I do not want a lecture on software engineering, thanks.

I can see how to hack the stupid warning out of moment well enough - that is likely easier than working out which bit of code here is causing some dumb error which obviously has no effect on users. Thanks for wasting my time.

The following line of code, really should not throw this warning...

// This throws the warning
moment( moment().toString() );

Why should I have to provide a string to format() just to tell moment to return to me a string that it deems acceptable?

This is a simplified test for what I imagine is a common use case of moment:

  • get the current time
  • save it to a database by invoking toString
  • ...later, get the current time and compare it to what was in the database using moment's compare features
  • decide what to do depending on how much time has elapsed

Is this deprecation warning being added in order to avoid moment needing to deal with browser inconsistencies? What good is a library if not for abstracting away inconsistencies? Am I missing something here?

Update: I discovered that this works if you change the example to:

// This does not throw the warning
moment( moment().format() );

This error is really confusing, and it links to this github issue (#1407) which does nothing to clear up what the error is or how to fix it. In addition, the error's stack trace doesn't include references back to the calling code, so it was very difficult to isolate the issue within my codebase. I finally figured it out, but what a total waste of time.

Same here, the stack trace is useless for me.

@lzilioli: Why not use moment().toISOString() instead? This solves the problem and is the same as calling moment.toJSON(). This means if you call toISOString() or toJSON() then your database version of the date will be the same, unambiguous ISO string as would be sent over the wire in a RESTful service.

var isoDateString = "2015-05-29T12:37:00.000Z";
var utcDateString = "Fri, 30 Jul 2010 15:05:00 UTC";
var test1 = moment(isoDateString, 'MM/DD/yyyy').isValid(); //test1 = false;
var test2 = moment(utcDateString, 'MM/dd/yyyy').isValid();  //test2 = false;

So neither the native JS ISO or UTC date formats are valid?? I'm not sure that this approach is the best idea... these are after all widely accepted standard formats to express date/time values in JS.