Safari JS не может проанализировать формат даты YYYY-MM-DD?

В проекте я продолжаю работать, я должен проверить дату, в которую вводят <input type="date">

С Safari 4/5 (на MAC OSX) JavaScript не удается проанализировать даты формата YYYY-MM-DD, возврат NaN вместо ожидаемой метки времени эпохи.

Я использую следующую технику для проверки поля непосредственно перед тем, как форма отправлена:

//value = '2010-06-21'
var stamp = Date.parse(value);
if (isNaN(stamp)) {
    //notify user
} else {
    value = new Date(stamp).format_mysql();
}

Где format_mysql() опытная функция, которая форматирует дату (правильно) в формат MySQL Date-Time (YYYY-MM-DD).

Замена -с /(YYYY/MM/DD) приводит к "корректной" метке времени.

Я должен отметить, что поле должно принять любой формат даты, не только YYYY-MM-DD, и что, хотя я хотел бы, я не могу пользоваться библиотеками как Date.js

Как я могу зафиксировать это или являюсь там лучшим способом анализировать/проверять дату?

37
задан Austin Hyde 21 June 2010 в 15:25
поделиться

3 ответа

Поведение метода Date.parse зависит от реализации, в ECMAScript 5 этот метод может анализировать даты в формате ISO8601, но я бы рекомендовал вам выполнить синтаксический анализ вручную.

Некоторое время назад я сделал простую функцию, которая может обрабатывать аргумент спецификатора формата:

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');

Также вы можете обнаружить поведение ECMAScript 5 для анализа дат в формате ISO, вы можете проверить, есть ли Date.prototype .toISOString доступен, например:

if (typeof Date.prototype.toISOString == "function") {
  // ES5 ISO date parsing available
}
57
ответ дан 27 November 2019 в 04:34
поделиться

Поле должно принимать любой формат даты

Вы имеете в виду не то, что думаете.

  • Трудно надежно отличить M/D/Y (США) от D/M/Y (Великобритания). D.M.Y более распространено в Великобритании, но ни в коем случае не универсально.
  • Удачи с датами до 1600 года - григорианский (солнечный) календарь был введен в 1582 году и был принят (в основном повсеместно) только в 20 веке (Википедия дает 1929 год). 30 февраля было действительной датой в Швеции.
  • OS X предоставляет вам выбор из 13 (!) календарей, хотя по умолчанию используется григорианский.

Вместо этого я рекомендую использовать виджет календаря. Я думаю, что у JQuery есть такой, но ICBW.

3
ответ дан 27 November 2019 в 04:34
поделиться

Вы можете получить однозначную дату из ввода, но вам все равно нужно проверить ее, чтобы пользователь не выдал вам 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> 

ярлык для document.getElementsByName

функция 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();
}

вы можете предварительно настроить поля так, чтобы они отражали текущую дату при загрузке

onload= function(){
    var now= new Date();
    byName('inputyear').value= now.getFullYear();
    byName('monthselect').selectedIndex= now.getMonth();
    byName('inputdate').value= now.getDate();
}
1
ответ дан 27 November 2019 в 04:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: