Safari JS cannot parse YYYY-MM-DD date format?
In a project I am working on, I need to validate a date entered into an <input type="date">
With Safari 4/5 (on Mac OSX) the Javascript fails to parse dates of the format YYYY-MM-DD
, returning NaN
instead of the expected epoch timestamp.
I am using the following technique to validate the field just before the form is submitted:
//value = '2010-06-21'
var stamp = Date.parse(value);
if (isNaN(stamp)) {
//notify user
} else {
value = new Date(stamp).format_mysql();
}
Where format_mysql()
is a prototype function that formats the date (correctly) into MySQL Date-Time format (YYYY-MM-DD).
Replacing the -
's with /
's (YYYY/MM/DD) yields a "correct" timestamp.
I should note that the field should accept any date format, not just YYYY-MM-DD, and that though I would like to, I cannot use libraries like Date.js
How can I fix this, or is there a better way to parse/validate a da开发者_Go百科te?
The behavior of the Date.parse
method is implementation dependent, on ECMAScript 5, this method can parse ISO8601 formatted dates, but I would recommend you to make the parsing manually.
Some time ago I've made a simple function, that can handle a format specifier argument:
function parseDate(input, format) {
format = format || 'yyyy-mm-dd'; // default format
var parts = input.match(/(\d+)/g),
i = 0, fmt = {};
// extract date-part indexes from the format
format.replace(/(yyyy|dd|mm)/g, function(part) { fmt[part] = i++; });
return new Date(parts[fmt['yyyy']], parts[fmt['mm']]-1, parts[fmt['dd']]);
}
parseDate('06.21.2010', 'mm.dd.yyyy');
parseDate('21.06.2010', 'dd.mm.yyyy');
parseDate('2010/06/21', 'yyyy/mm/dd');
parseDate('2010-06-21');
Also you could detect the ECMAScript 5 behavior to parse ISO formatted dates, you can check if the Date.prototype.toISOString
is available, e.g.:
if (typeof Date.prototype.toISOString == "function") {
// ES5 ISO date parsing available
}
Generally DD-MM-YYYY format is not support in safari.
value = 2010/06/21 ; //should work.
(or)
value = new Date('2010-06-21'.replace(/-/g, "/"));
the field should accept any date format
You don't mean what you think you mean.
- It's difficult to reliably distinguish between M/D/Y (US) and D/M/Y (UK). D.M.Y is more common in the UK, but by no means universal.
- Good luck with dates before around 1600 — the Gregorian (solar) calendar was introduced in 1582, and was only (mostly universally) adopted in the 20th century (Wikipedia gives 1929). February 30 was a valid date Sweden.
- OS X gives you a choice of 13 (!) calendars, though the default is Gregorian.
Instead, I recommend using a calendar widget. I think JQuery has one, but ICBW.
You can get an unambiguous date from input, but you still need to check it, so a user doesn't give you April 31.
<fieldset id= "localdate">
<select id= "monthselect" size= "1">
<option selected= "selected"> January</option>
<option> February</option>
<option> March</option>
<option> April</option>
<option> May</option>
<option> June</option>
<option> July</option>
<option> August</option>
<option> September</option>
<option> October</option>
<option> November</option>
<option> December</option>
</select>
<label> Date: <input name= "inputdate" size= "2" value= "1"> </label>
<label> Year: <input name= "inputyear" size= "4" value= "2010"> </label>
</fieldset>
shortcut for document.getElementsByName
function byName(s, n){ n= n || 0; return document.getElementsByName(s)[n]; }
function getDateInput(){
var day, y= parseInt(byName('inputyear').value),
m= byName('monthselect').selectedIndex,
d= parseInt(byName('inputdate').value);
if(!y || y<1000 || y> 3000) throw 'Bad Year '+y;
if((!d || d<1 || d> 32) throw 'Bad Date '+d;
day= new Date(y,m,d);
if(day.getDate()!= d) throw 'Bad Date '+d;
value= day.format_mysql();
}
you can preset the fields to reflect the current date onload
onload= function(){
var now= new Date();
byName('inputyear').value= now.getFullYear();
byName('monthselect').selectedIndex= now.getMonth();
byName('inputdate').value= now.getDate();
}
精彩评论