Safari JS не может разобрать формат даты ГГГГ-ММ-ДД? - PullRequest
37 голосов
/ 21 июня 2010

В проекте, над которым я работаю, мне нужно проверить дату, введенную в <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.js

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

Ответы [ 4 ]

57 голосов
/ 21 июня 2010

Поведение метода 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
}
12 голосов
/ 08 октября 2013

Обычно формат DD-MM-YYYY не поддерживается в сафари.

значение = 2010/06/21; // должно работать.

(или)

значение = новая дата ('2010-06-21'. Место (/ - / g, "/"));

3 голосов
/ 21 июня 2010

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

Ты не имеешь в виду то, что думаешь.

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

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

1 голос
/ 21 июня 2010

Вы можете получить однозначную дату из ввода, но вам все еще нужно проверить ее, чтобы пользователь не дал вам 31 апреля.* function byName (s, n) {n = n ||0;вернуть 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...