-
Notifications
You must be signed in to change notification settings - Fork 7.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Invalid moment rework #1140
Invalid moment rework #1140
Conversation
OK, this is a long PR! The main test file: About the DST -- to be honest I don't like the Now the week tokens (#1141) would be hard to incorporate. If we can convert a week date to a regular year, month, day then we can just use a complete date-time array to initialize Date, and then compare arrays for DST. If we first set the date components only (year, month, day OR iso week year, iso week, iso weekday OR local variant) then its possible for the date part to fall into DST, for those DST that start at 00:00 at some day, which would render a day that's off by one. The rest seems fine. |
Haha, oops.
Sure. That's a bit more code, but it does fix some edge cases with the DST check. Will fix. On the week tokens, good catch; for some reason I never thought of that issue, when writing #1141. So I propose we merge this first and then I'll rework #1141 as appropriate (see my notes there - it's a bit of work). I'll patch up the items above in the next day or two, and also get it up to date with the develop branch. |
@ichernev made a few changes:
|
m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND : | ||
-1; | ||
|
||
if (m._pf._overflowDayOfYear && (overflow < 0 || overflow > 2)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 should be DATE. Here and on next line, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup, fixed
@@ -1158,6 +1206,25 @@ | |||
} | |||
} | |||
|
|||
function makeDate(y, m, d, h, M, s, ms) { | |||
//can't just apply() to create a date: | |||
//http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JS has some really weird corners...
var date = new Date(y, m, d, h, M, s, ms); | ||
|
||
//the date constructor doesn't accept years < 1970 | ||
if (y < 1970) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are probably some edge cases caused here. If the post 1970 date JS uses is on a DST, then this'll get shifted, even if the pre-1970 date wouldn't have been. But since a lot of the browsers (all of them on Windows, for example), don't support different historic rules anyway, I'm not sure this is the biggest deal. I'm open to suggestions, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, wow. I did not foresee that Javascript bump :) Dates before 1970 are used much less anyway, and I really don't see something we can do about them. The current implementation is much worse in regard to DST shifting issues, so I guess we can stick with this one for a while.
Ok, that looks great! We can create a date object from date and time, yeey :) I think this PR turned out great, I just hope momen't users won't be disappointed by the change in Thank you for the hard work! |
👍 |
Apologies for the number of commits here; it was hard to squash them because I merged in
develop
instead of rebasing (which I had to do because part of the branch was already merged. Here's a summary of the changes:Parsing flags
We generate a set of parsing flags when parsing with a format. They are:
Access with
moment().parsingFlags()
. Note that the flags do not includedstInvalid
.Redefined isValid
isValid()
is now a function of three things:date.valueOf()
justNaN
?Which parsing flags matter is determined by
strict
. This makes it a lot easier to understand and diagnose validity. There are some behavioral changes. In general,isValid()
is more lenient. Some examples:moment('xx-xx-2001', 'DD-MM-YY')
was invalid and now isn't. That's because it parses as Jan 20. I think this is correct. Use strict if you don't want that.`moment('123456790.12', 'X.SS') was invalid and now isn't.
Open questions:
isValid()
completely ignores whether the date parsed corresponds to a time that doesn't exist because of DST. This is a significant change breaking change. Should it check that?Improved format scoring
As of #1094, we do a much better job of picking a parsing format out of a list by checking how many unparsed characters there are. We can use the parsing flags to improve that:
isValid()
Reworked strict parsing
Strict parsing doesn't need its own separate function to check things. We just have
strict
behave differently in these ways:^
to the token regexes. This works because weslice()
the string progressivelyunsedTokens
parsing flagisValid()
consider additional parsing flagsOpen stuff:I need additional tests for that third item.This is covered by the create() testsisDSTShifted
We want to know if you asked for 1:30 AM on March 3 (assuming you're in the US).
isDSTShifted()
answers that. There are a few questions/issues there:isDSTShifted
the right term for this?isDSTInvalid()
?isUnexpectedTime
? Don't know what to call it.overflowMonthOk
flag is off, that the only reason for_a != moment(_a).toArray()
is that DST messed with the date. I'm not 100% sure that's true.format() for invalid moments
format()
always returns "Invalid date" for!m.isValid()
. The string can be localized.Open issues:
Could use more tests in generaldoneNeed to test localizationdoneLittle stuff
moment.invalid()
now takes an optional object of parsing flags. So if you're making a third-party plugin, you can generate moments with the appropriate flags, even made-up ones. If you don't specify flags, it sets theuserInvalidated
flag for you.Other internal changes