Проверьте, является ли строка значением даты

Что такое простой способ проверить, является ли значение допустимой датой, любой известный формат даты разрешен.

Например, у меня есть значения 10-11-2009, 10/11/2009, 2009-11-10T07:00:00+0000, которые должны быть признаны как значения даты, а значения 200, 10, 350, которые не должны распознаваться как значение даты. Каков самый простой способ проверить это, если это возможно? Поскольку временные метки также будут разрешены.

Ответ 2

Обновление 2015 года

Это старый вопрос, но другие новые вопросы:

закройте как дубликаты этого, поэтому я думаю, что важно добавить здесь свежую информацию. Я пишу это, потому что я испугался, думая, что люди действительно копируют и вставляют часть кода, размещенного здесь, и используют его в производстве.

Большинство ответов здесь либо используют некоторые сложные регулярные выражения, которые соответствуют только некоторым очень конкретным форматам, и на самом деле делают это неправильно (например, сопоставление 32-го января, а не сопоставление фактической даты ISO, как рекламируется - см. Демонстрацию) или они пытаются передать что-либо конструктору Date и желаем лучшего.

Использование Moment

Как я объяснил в этом ответе, в настоящее время для этого доступна библиотека: Moment.js

Это библиотека для анализа, проверки, обработки и отображения дат в JavaScript, которая имеет гораздо более богатый API, чем стандартные функции обработки дат JavaScript.

Это 12kB minified/gzipped и работает в Node.js и в других местах:

bower install moment --save # bower
npm install moment --save   # npm
Install-Package Moment.js   # NuGet
spm install moment --save   # spm
meteor add momentjs:moment  # meteor

Используя Moment, вы можете быть очень конкретным относительно проверки правильных дат. Иногда очень важно добавить некоторые подсказки о формате, который вы ожидаете. Например, дата, такая как 06/22/2015, выглядит как действительная дата, если вы не используете формат DD/MM/YYYY, и в этом случае эта дата должна быть отклонена как недействительная. Есть несколько способов, как вы можете сказать Moment, какой формат вы ожидаете, например:

moment("06/22/2015", "MM/DD/YYYY", true).isValid(); // true
moment("06/22/2015", "DD/MM/YYYY", true).isValid(); // false

true аргумент заключается в том, что Moment не будет пытаться разобрать вход, если он точно не соответствует одному из предоставленных форматов (по-моему, это должно быть поведение по умолчанию).

Вы можете использовать внутренний формат:

moment("2015-06-22T13:17:21+0000", moment.ISO_8601, true).isValid(); // true

И вы можете использовать несколько форматов в виде массива:

var formats = [
    moment.ISO_8601,
    "MM/DD/YYYY  :)  HH*mm*ss"
];
moment("2015-06-22T13:17:21+0000", formats, true).isValid(); // true
moment("06/22/2015  :)  13*17*21", formats, true).isValid(); // true
moment("06/22/2015  :(  13*17*21", formats, true).isValid(); // false

См. DEMO.

Другие библиотеки

Если вы не хотите использовать Moment.js, есть и другие библиотеки:

Обновление 2016 года

Я создал модуль immoment, подобный (подмножество) Moment, но без сюрпризов, вызванных мутацией существующих объектов (подробнее см. В документах).

Обновление 2018 года

Сегодня я рекомендую использовать Luxon для обработки даты/времени вместо Moment, который (в отличие от Moment) делает весь объект неизменным, поэтому нет неприятных сюрпризов, связанных с неявной мутацией дат.

Больше информации

Смотрите также:

Серия статей Роба Гравелла по JavaScript-синтаксическому анализу:

Нижняя линия

Конечно, каждый может попробовать изобрести колесо, написать регулярное выражение (но, пожалуйста, на самом деле читать ISO 8601 и RFC 3339, прежде чем это сделать) или позвоните буит в конструкторах со случайными данными для синтаксического анализа сообщения об ошибках, как 'Invalid Date' (Вы что это сообщение абсолютно одинаково на всех платформах? Во всех локалях? В будущем?), или вы можете использовать проверенное решение и использовать свое время, чтобы улучшить его, а не изобретать его повторно. Все перечисленные здесь библиотеки являются свободным программным обеспечением с открытым исходным кодом.

Ответ 3

Вот как я решил эту проблему в приложении, над которым я сейчас работаю:

обновлено на основе отзывов от крильгара:

var isDate = function(date) {
    return (new Date(date) !== "Invalid Date") && !isNaN(new Date(date));
}

или же...

var isDate = function(date) {
    return (new Date(date) !== "Invalid Date" && !isNaN(new Date(date)) ) ? true : false;
}

....

Ответ 4

new Date(date) === 'Invalid Date' работает только в Firefox и Chrome. IE8 (тот, который у меня есть на моей машине для тестирования) дает NaN.

Как было сказано к принятому ответу, Date.parse(date) также будет работать для чисел. Поэтому, чтобы обойти это, вы также можете проверить, что это не число (если это то, что вы хотите подтвердить).

var parsedDate = Date.parse(date);

// You want to check again for !isNaN(parsedDate) here because Dates can be converted
// to numbers, but a failed Date parse will not.
if (isNaN(date) && !isNaN(parsedDate)) {
    /* do your work */
}

Ответ 5

Как насчет этого? Он проверит, является ли это объектом Date или строкой даты:

function isDate(value) {
    var dateFormat;
    if (toString.call(value) === '[object Date]') {
        return true;
    }
    if (typeof value.replace === 'function') {
        value.replace(/^\s+|\s+$/gm, '');
    }
    dateFormat = /(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/;
    return dateFormat.test(value);
}

Я должен отметить, что это не проверяет строки, отформатированные в ISO, но с небольшим количеством работы с RegExp вы должны быть хорошими.

Ответ 6

Ни один из ответов здесь не проверяет, является ли дата недействительной, например, 31 февраля. Эта функция обращается к этому, проверяя, соответствует ли возвращенный месяц первоначальному месяцу, и убедитесь, что был представлен действительный год.

//expected input dd/mm/yyyy or dd.mm.yyyy or dd-mm-yyyy
function isValidDate(s) {
  var separators = ['\\.', '\\-', '\\/'];
  var bits = s.split(new RegExp(separators.join('|'), 'g'));
  var d = new Date(bits[2], bits[1] - 1, bits[0]);
  return d.getFullYear() == bits[2] && d.getMonth() + 1 == bits[1];
} 

Ответ 7

Используйте регулярное выражение, чтобы проверить его.

isDate('2018-08-01T18:30:00.000Z');

isDate(_date){
        const _regExp  = new RegExp('^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$');
        return _regExp.test(_date);
    }

Ответ 8

Я бы сделал это

var myDateStr= new Date("2015/5/2");

if( ! isNaN ( myDateStr.getMonth() )) {
    console.log("Valid date");
}
else {
    console.log("Invalid date");
}

Воспроизвести здесь

Ответ 9

Отправляя все вышеперечисленные комментарии, я пришел к решению.

Это работает, если дата прошла в формате ISO или должна использоваться для других форматов.

var isISO = "2018-08-01T18:30:00.000Z";

if(new Date(isISO) !== "Invalid Date" && !isNaN(new Date(isISO)) ) {
if(isISO==new Date(isISO).toISOString()){
console.log("Valid date");
} else {
    console.log("Invalid date");
    }

}
else {
    console.log("Invalid date");
}'

вы можете играть здесь на JSFiddle

Ответ 10

Здесь минималистская версия.

var isDate = function (date) {
    return!!(function(d){return(d!=='Invalid Date'&&!isNaN(d))})(new Date(date));
}

Ответ 11

После прочтения всех ответов, перечисленных выше, я получил следующее:

var checkDateValue = function(date) {
    return date && (!(new Date(date) == "Invalid Date") && !isNaN(new Date(date)));
};

Обратите внимание, что new Date(date) !== "Invalid Date" имеет значение всегда. Надеюсь, это поможет.

Ответ 12

Эта вызываемая функция работает отлично, возвращает true для допустимой даты. Обязательно звоните с использованием даты в формате ISO (yyyy-mm-dd или yyyy/mm/dd):

function validateDate(isoDate) {

    if (isNaN(Date.parse(isoDate))) {
        return false;
    } else {
        if (isoDate != (new Date(isoDate)).toISOString().substr(0,10)) {
            return false;
        }
    }
    return true;
}

Ответ 13

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

 var year=2019;
 var month=2;
 var date=31;
 var d = new Date(year, month - 1, date);
 if (d.getFullYear() != year
    || d.getMonth() != (month - 1)
    || d.getDate() != date) {
alert("invalid date");
return false;
}

Ответ 14

Я знаю, что это старый вопрос, но я столкнулся с одной и той же проблемой и увидел, что ни один из ответов не работал должным образом - в частности, отбрасывание чисел (1200, 345 и т.д.) Из дат, что является исходным вопросом. Вот довольно неортодоксальный метод, о котором я мог думать, и, похоже, он работает. Пожалуйста, укажите, есть ли случаи, когда он потерпит неудачу.

if(sDate.toString() == parseInt(sDate).toString()) return false;

Это линия для отсечения чисел. Таким образом, вся функция может выглядеть так:

function isDate(sDate) {  
  if(sDate.toString() == parseInt(sDate).toString()) return false; 
  var tryDate = new Date(sDate);
  return (tryDate && tryDate.toString() != "NaN" && tryDate != "Invalid Date");  
}

console.log("100", isDate(100));
console.log("234", isDate("234"));
console.log("hello", isDate("hello"));
console.log("25 Feb 2018", isDate("25 Feb 2018"));
console.log("2009-11-10T07:00:00+0000", isDate("2009-11-10T07:00:00+0000"));

Ответ 15

Хорошо ли проверить, что функция, связанная с датой, доступна для объекта, чтобы определить, является ли это объектом Date или нет?

like

var l = new Date();
var isDate = (l.getDate !== undefined) ? true; false;

Ответ 16

Вот как я это делаю. Это не распространяется на все форматы. Вы должны соответствующим образом настроить. У меня есть контроль над форматом, поэтому он работает для меня

function isValidDate(s) {
            var dt = "";
            var bits = [];
            if (s && s.length >= 6) {
                if (s.indexOf("/") > -1) {
                    bits = s.split("/");
                }
                else if (s.indexOf("-") > -1) {
                    bits = s.split("-");
                }
                else if (s.indexOf(".") > -1) {
                    bits = s.split(".");
                }
                try {
                    dt = new Date(bits[2], bits[0] - 1, bits[1]);
                } catch (e) {
                    return false;
                }
                return (dt.getMonth() + 1) === parseInt(bits[0]);
            } else {
                return false;
            }
        }

Ответ 17

Попробуй это

<input type="text" id="StartDay" value="2018/01/01" maxlength="10" />

$('#StartDay').change(function () {
    if ( ($('#StartDay').val().length == 10 && new Date($('#StartDay').val()) >= new Date("2018/01/01") &&
        (new Date($('#StartDay').val()) !== "Invalid Date") && !isNaN(new Date($('#StartDay').val()))) == false) {
     .....
    }
})

Ответ 18

Для этого я создал решение на основе moment.js для обнаружения ISO 8601, RFC 2822 и локальных форматов, без необходимости указывать строку синтаксического анализа (которую я всегда не хочу вводить в "стандартном" формате.)...

https://github.com/patarapolw/valid-moment

Ответ 19

Короткий путь:

if(!isNaN(Date.parse(date)))

Ответ 20

Это работает:

var isDate = function(date) {
    return ((new Date(date)).toString() !== "Invalid Date") ? true : false;         
}

Ответ 21

Хорошо, это старый вопрос, но я нашел другое решение при проверке решений здесь. Для меня работает, чтобы проверить, присутствует ли функция getTime() в объекте даты:

const checkDate = new Date(dateString);

if (typeof checkDate.getTime !== 'function') {
  return;
}

Ответ 22

Ниже немного более улучшенный метод, который использует Date.parse(), но проверяет, является ли ввод не числом:

function isDate(s) {
    if(isNaN(s) && !isNaN(Date.parse(s))
        return true;
    else return false;
}

Примечание: Date.parse() будет анализировать числа: например, Date.parse(1) вернет дату. Итак, здесь мы проверяем, не является ли s числом, является ли это датой.

Ответ 23

SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
sdf.setLenient(false);

По умолчанию установлено значение TRUE. Таким образом, даже строки неправильного формата возвращают хорошие значения.

Я использовал его примерно так:

SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
formatter.setLenient(false);
String value = "1990/13/23"; 

try {
      Date date = formatter.parse(value);
      System.out.println(date);
    }catch (ParseException e) 
  {
    System.out.println("its bad");
  }

Ответ 24

Попробуйте следующее:

if (var date = new Date(yourDateString)) {
    // if you get here then you have a valid date       
}