How do I parse a Date with moment.js(or alternative library) to pick out 31st Feb or 31st June e,t,c, as invalid?
I know that if I did
moment("20-02-2000");
it says
Moment {_isAMomentObject: true, _i: "20-02-2000",
_isUTC: false, _locale: Locale, _d: Invalid Date}
So it can detect an invalid date, that's good
Though i'm using yyyy-mm-dd
I don't seem to be able to get it to parse a Date
moment("2000-02-31");
Moment {_isAMomentObject: true, _i: "2000-02-31",
_f: "YYYY-MM-DD", _isUTC: false, _pf: Object…}
^^ nothing about invalid date there
moment("2000-02-40");
Moment {_isAMomentObject: true, _i: "2000-02-40",
_f: "YYYY-MM-DD", _isUTC: false, _pf: Object…}
^^ nothing about invalid date there
moment("2000-40-01");
Moment {_isAMomentObject: true, _i: "2000-40-01",
_f: "YYYY-MM-DD", _isUTC: false, _pf: Object…}
^^ nothing about invalid date there
added
var v=moment("2000-02-31");
v.toDate()
Thu Mar 02 2000 00:00:00 GMT+0000 (GMT Standard Time)
^^ I see that if I give an invalid date like 31st feb, that it normalizes it, but I want it to just say invalid.
I'm looking for a function where I give it "2000-31-02" it says invalid date.
I have seen moment.js suggested as an alternative to javascript's Date constructor. I looked at moment.js because javascript's Date constructor also parses 31st Feb without saying invalid javascript Date.parse assumes 31 days in February and all months? . So I was hoping that moment.js would be able to do it. If it can, then how? And if not, then is there an alternative to moment.js that does it?
I'm looking for a library I can import, rather than reinventing the wheel.
How do I parse a Date with moment.js(or alternative library) to pick out 31st Feb or 31st June e,t,c, as invalid?
I know that if I did
moment("20-02-2000");
it says
Moment {_isAMomentObject: true, _i: "20-02-2000",
_isUTC: false, _locale: Locale, _d: Invalid Date}
So it can detect an invalid date, that's good
Though i'm using yyyy-mm-dd
I don't seem to be able to get it to parse a Date
moment("2000-02-31");
Moment {_isAMomentObject: true, _i: "2000-02-31",
_f: "YYYY-MM-DD", _isUTC: false, _pf: Object…}
^^ nothing about invalid date there
moment("2000-02-40");
Moment {_isAMomentObject: true, _i: "2000-02-40",
_f: "YYYY-MM-DD", _isUTC: false, _pf: Object…}
^^ nothing about invalid date there
moment("2000-40-01");
Moment {_isAMomentObject: true, _i: "2000-40-01",
_f: "YYYY-MM-DD", _isUTC: false, _pf: Object…}
^^ nothing about invalid date there
added
var v=moment("2000-02-31");
v.toDate()
Thu Mar 02 2000 00:00:00 GMT+0000 (GMT Standard Time)
^^ I see that if I give an invalid date like 31st feb, that it normalizes it, but I want it to just say invalid.
I'm looking for a function where I give it "2000-31-02" it says invalid date.
I have seen moment.js suggested as an alternative to javascript's Date constructor. I looked at moment.js because javascript's Date constructor also parses 31st Feb without saying invalid javascript Date.parse assumes 31 days in February and all months? . So I was hoping that moment.js would be able to do it. If it can, then how? And if not, then is there an alternative to moment.js that does it?
I'm looking for a library I can import, rather than reinventing the wheel.
Share Improve this question edited May 23, 2017 at 11:51 CommunityBot 11 silver badge asked Aug 29, 2015 at 12:30 barlopbarlop 13.9k9 gold badges87 silver badges125 bronze badges 4- If you parse such invalid with "YYYY-MM-DD", and then turn around and format them in the same format, does it give you back the same (invalid) string, or does it normalize Feb 31 to Mar 3? – Pointy Commented Aug 29, 2015 at 13:04
- @Pointy I just added a bit to my q to test that, and I see that it normalizes it, but i'm not looking for it to normalize an invalid date. I just want it to detect/say invalid date. – barlop Commented Aug 29, 2015 at 13:20
- Wee my point is that if you get back a different string than you gave it, then the date must be invalid. – Pointy Commented Aug 29, 2015 at 13:27
- also stackoverflow./questions/19978953/… – Pointy Commented Aug 29, 2015 at 13:29
4 Answers
Reset to default 2You can check if moment thinks a date is valid using moment().isValid()
first.
console.log(moment('2015-02-31').isValid());
//false
http://jsfiddle/nicholasduffy/uv8aqykm/
http://momentjs./docs/#/parsing/string-format/
Moment.js provides the isValid
method to check whether the parsed string is valid or not.
moment("2000-02-28").isValid(); //true
moment("2000-02-31").isValid(); //false
moment("2000-02-40").isValid(); //false
Is this the behaviour you're looking for?
You can read more about this method here http://momentjs./docs/#/parsing/is-valid/
The proposed format (YYYY-DD-MM) must be reformatted to YYYY-MM-DD or Javascript Date constructor will return an invalid date error.
Thus said, the Date constructor will still accept 2000-02-31 and convert it to 2001-03-02. So you must preprocess it.
When you have preprocessed the string and have a Date constructor valid format you can use the below code to convert to date. Below code also gives you an opportunity to check if a date string is valid and if a year is a leap year.
var dso = {
convert:function(d) {
// Converts the date in d to a date-object. The input can be:
// a date object: returned without modification
// an array : Interpreted as [year,month,day].
// a number : Interpreted as number of milliseconds
// since 1 Jan 1970 (a timestamp)
// a string : Any format supported by the javascript engine, like
// "YYYY/MM/DD", "MM/DD/YYYY", "Jan 31 2009" etc.
// an object : Interpreted as an object with year, month and date
// attributes.
return (
d.constructor === Date ? d :
d.constructor === Array ? new Date(d[0],d[1]-1,d[2]) :
d.constructor === Number ? new Date(d) :
d.constructor === String ? new Date(d) :
typeof d === "object" ? new Date(d.year,d.month-1,d.date) :
NaN
);
},
isvalid(d,f) {
// optional formats possible, see switch statement
var m = [0,31,28,31,30,31,30,31,31,30,31,30,31], t,a;
if (d.constructor == String) {
d = d.replace("/","-").replace(".","-").replace(", ","-").replace(",","-").replace(" ","");
t = d.split("-"), t[0] = parseInt(t[0]), t[1] = parseInt(t[1]), t[2] = parseInt(t[2]);
switch(f) {
case "yyyy-dd-mm":
a = (dso.leapyear(t[0])?1:0);
if (t[2] > 12 || t[2] < 1) return false;
if (t[1] < 1 || (t[1] + a) > m[parseInt(t[2])]) return false;
break;
case "dd-mm-yyyy":
a = (dso.leapyear(t[2])?1:0);
if (t[1] > 12 || t[1] < 1) return false;
if (t[0] < 1 || (t[0] + a) > m[parseInt(t[1])]) return false;
break;
case "mm-dd-yyyy":
a = (dso.leapyear(t[2])?1:0);
if (t[0] > 12 || t[0] < 1) return false;
if (t[1] < 1 || (t[1] + a) > m[parseInt(t[0])]) return false;
break;
case "mm-yyyy-dd":
a = (dso.leapyear(t[1])?1:0);
if (t[0] > 12 || t[0] < 1) return false;
if (t[2] < 1 || (t[2] + a) > m[parseInt(t[0])]) return false;
break;
case "yyyy-mm-dd":
default:
a = (dso.leapyear(t[0])?1:0);
if (t[1] > 12 || t[1] < 1) return false;
if (t[2] < 1 || (t[2] + a) > m[parseInt(t[1])]) return false;
break;
}
return true;
}
},
leapyear: function(year) {
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0 || year == 4905 || year == 8228) return true;
return false;
}
}
There is the isValid method, but you should specify the format too, to moment..
e.g. moment("2000-02-31", "YYYY-MM-DD").isValid()
Interestingly the javascript console wasn't showing isValid() when typing moment dot. or moment.prototype.
The docs say
The Moment prototype is exposed through moment.fn
isValid does show for moment.fn.
And it gets it right, including even the leap year rule for centuries, that a century is a leap year if it's both divisible by 4 and by 400.
moment("2000-02-31", "YYYY-MM-DD").isValid()
false
moment("2000-02-28", "YYYY-MM-DD").isValid()
true
moment("2100-02-28", "YYYY-MM-DD").isValid()
true
moment("2100-02-29", "YYYY-MM-DD").isValid()
false
moment("2000-02-29", "YYYY-MM-DD").isValid()
true
Must be capital Ds
moment("2000-02-40","YYYY-MM-dd").isValid()
true
moment("2000-02-40","YYYY-MM-DD").isValid()
false
And you may want to use a regex to check that it is yyyy-mm-dd or mm-dd-yyyy etc because it still accepts 2000.9 or slashes/ whatever delimiter
moment("2000/02/20","YYYY-MM-DD").isValid()
true
moment("2000/52/20","YYYY-MM-DD").isValid()
false
moment("2000.9","YYYY-MM-DD").isValid()
true
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744889816a4599336.html
评论列表(0条)