Regex для проверки формата даты dd/mm/yyyy
Мне нужно проверить строку даты для формата dd/mm/yyyy
с регулярным выражением.
Это регулярное выражение проверяет dd/mm/yyyy
, но не такие недопустимые даты, как 31/02/4500
:
^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}$
Что такое действительное регулярное выражение для проверки формата dd/mm/yyyy
с поддержкой високосного года?
Ответы
Ответ 1
Прикрепленное вами регулярное выражение не правильно проверяет високосные годы, но есть тот, который делает в том же сообщении.
Я изменил его, чтобы взять dd/mm/yyyy
, dd-mm-yyyy
или dd.mm.yyyy
^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$
Я немного протестировал его в ссылке, предоставленной в его ответе, а также здесь и, похоже, работает.
Ответ 2
Я расширил регулярное выражение, данное @Ofir Luzon для форматов dd-mmm-YYYY, dd/mmm/YYYY, dd.mmm.YYYY согласно моему требованию. Любой другой с таким же требованием может ссылаться на этот
^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]|(?:Jan|Mar|May|Jul|Aug|Oct|Dec)))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2]|(?:Jan|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)(?:0?2|(?:Feb))\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9]|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep))|(?:1[0-2]|(?:Oct|Nov|Dec)))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$
и протестирован для некоторых тестовых примеров здесь http://regexr.com/39tr1.
Для лучшего понимания этого регулярного выражения см. это изображение:
![enter image description here]()
Ответ 3
Обратите внимание:
Ваше регулярное выражение не работает в течение многих лет, которое "кратно 4 и 100, но не 400". Годы, которые проходят этот тест, не високосные годы. Например: 1900, 2100, 2200, 2300, 2500 и т.д. Другими словами, он переносит все годы в формате \d\d00 в тот же класс високосных годов, что неверно. - MuchToLearn
Поэтому он работает правильно только для [1901 - 2099] (Whew) 😊
дд/мм/гггг:
Проверяет ли високосный год. Годы с 1900 по 9999 год действительны. Только dd/MM/yyyy
(^(((0[1-9]|1[0-9]|2[0-8])[\/](0[1-9]|1[012]))|((29|30|31)[\/](0[13578]|1[02]))|((29|30)[\/](0[4,6,9]|11)))[\/](19|[2-9][0-9])\d\d$)|(^29[\/]02[\/](19|[2-9][0-9])(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)$)
Ответ 4
попробуйте это.
^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$
вы можете легко тестировать регулярное выражение http://www.regular-expressions.info/javascriptexample.html.
Ответ 5
Для тех, кто смотрит на них и становится совершенно смущенным, вот отрывок из моего script. К сожалению, все, что он делает, соответствует допустимым числам во входном сигнале даты, а 31 февраля будет отмечен как действительный, но, как многие говорили, regex действительно не лучший инструмент для этого теста.
Чтобы соответствовать дате в формате "yyyy-MM-dd hh: mm" (или, в любом случае, в любом порядке)
var dateerrors = false;
var yearReg = '(201[4-9]|202[0-9])'; ///< Allows a number between 2014 and 2029
var monthReg = '(0[1-9]|1[0-2])'; ///< Allows a number between 00 and 12
var dayReg = '(0[1-9]|1[0-9]|2[0-9]|3[0-1])'; ///< Allows a number between 00 and 31
var hourReg = '([0-1][0-9]|2[0-3])'; ///< Allows a number between 00 and 24
var minReg = '([0-5][0-9])'; ///< Allows a number between 00 and 59
var reg = new RegExp('^' + yearReg + '-' + monthReg + '-' + dayReg + ' ' + hourReg + ':' + minReg + '$', 'g');
$('input').filter(function () {return this.id.match(/myhtml_element_with_id_\d+_datetime/);}).each(function (e) {
if (e > 0) {
// Don't test the first input. This will use the default
var val = $(this).val();
if (val && !val.trim().match(reg)) {
dateerrors = true;
return false;
}
}
});
if (dateerrors) {
alert('You must enter a validate date in the format "yyyy-mm-dd HH:MM", e.g. 2019-12-31 19:30');
return false;
}
Вышеупомянутый script начинается с создания объекта регулярного выражения. Затем он находит все входы, чей идентификатор соответствует определенному шаблону, а затем пересекает их. Я не тестирую первый вход, который я нахожу (if (e > 0)
).
Немного объяснения:
var reg = new RegExp('^' + yearReg + '-' + monthReg + '-' + dayReg + ' ' + hourReg + ':' + minReg + '$', 'g');
^
означает начало совпадения, тогда как $
означает конец матча.
return this.id.match(/myhtml_element_with_id_\d+_datetime/);
\d+
означает совпадение одиночной или непрерывной последовательности целых чисел, поэтому myhtml_element_with_id_56_datetime
и myhtml_element_with_id_2_datetime
будут соответствовать, но myhtml_element_with_id_5a_datetime
не будет
Ответ 6
Вот еще одна версия регулярного выражения, которая соответствует любому из следующих форматов дат и позволяет исключить ведущие нули:
Regex: ^[0-3]?[0-9].[0-3]?[0-9].(?:[0-9]{2})?[0-9]{2}$
Матчи:
1/1/11 or 1.1.11 or 1-1-11 : true
01/01/11 or 01.01.11 or 01-01-11 : true
01/01/2011 or 01.01.2011 or 01-01-2011 : true
01/1/2011 or 01.1.2011 or 01-1-2011 : true
1/11/2011 or 1.11.2011 or 1-11-2011 : true
1/11/11 or 1.11.11 or 1-11-11 : true
11/1/11 or 11.1.11 or 11-1-11 : true
![Regular expression visualization]()
Демоверсия Debuggex
Ответ 7
Я подозреваю, что следующее так же точно, как можно ожидать, не зная, когда пользовательский язык переключился с юлианских на григорианские календари.
Он принимает либо '-', '/', либо ничего как разделители между годом, месяцем и днем, независимо от порядка.
ММДДГГГГ:
^(((0[13-9]|1[012])[-/]?(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])[-/]?31|02[-/]?(0[1-9]|1[0-9]|2[0-8]))[-/]?[0-9]{4}|02[-/]?29[-/]?([0-9]{2}(([2468][048]|[02468][48])|[13579][26])|([13579][26]|[02468][048]|0[0-9]|1[0-6])00))$
DDMMYYYY:
^(((0[1-9]|[12][0-9]|30)[-/]?(0[13-9]|1[012])|31[-/]?(0[13578]|1[02])|(0[1-9]|1[0-9]|2[0-8])[-/]?02)[-/]?[0-9]{4}|29[-/]?02[-/]?([0-9]{2}(([2468][048]|[02468][48])|[13579][26])|([13579][26]|[02468][048]|0[0-9]|1[0-6])00))$
YYyyMmDd:
^([0-9]{4}[-/]?((0[13-9]|1[012])[-/]?(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])[-/]?31|02[-/]?(0[1-9]|1[0-9]|2[0-8]))|([0-9]{2}(([2468][048]|[02468][48])|[13579][26])|([13579][26]|[02468][048]|0[0-9]|1[0-6])00)[-/]?02[-/]?29)$
Помимо заказа, все они верны Юлийскому календарю (високосный год каждые четыре года) до 1700 года, когда Григорианский календарь расходится с Юлианом. У этого есть два вопроса:
- Он принимает год 0000, который не существует во многих, но не во всех стандартах. Обратите внимание, что ISO 8601 действительно принимает год 0000 (эквивалентно 1 BCE).
- Он не пропускает 10-13 дней, которые были потеряны, когда григорианский календарь был использован. Однако это зависит от местоположения. Например, Римско-католическая церковь пропустила 10 дней, с 5 октября по 14 октября 1582 года, но Греция (последняя для переключения) пропустила с 16 по 28 февраля 1923 года, 13 дней, принимая во внимание високосные годы 1700 года, 1800 и 1900 г.
Это было протестировано против реализации Java-календаря с 0001 года до 9999 года, при этом единственным несоответствием было упомянутое 10 дней в 1582 году.
Ответ 8
Найден этот рег здесь
^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$
Это корректно проверяет формат mm/dd/yyyy
и правильные даты (но не m/d/yyyy
).
Некоторые тесты
Ответ 9
"^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.]((19|20)\\d\\d)$"
будет проверять любую дату между 1900-2099
Ответ 10
Следующее выражение красиво и легко манипулировать:
((((0[13578]|1[02])(\/|-|.)(0[1-9]|1[0-9]|2[0-9]|3[01]))|((0[469]|11)(\/|-|.)(0[1-9]|1[0-9]|2[0-9]|3[0]))|((02)((\/|-|.)(0[1-9]|1[0-9]|2[0-8]))))(\/|-|.)(19([6-9][0-9])|20(0[0-9]|1[0-4])))|((02)(\/|-|.)(29)(\/|-|.)(19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26])))
Он проверяется в соответствии с форматом MM/dd/YYYY и позволяет поддерживать високосный год с 1960 по 2016 год. Если вам нужна поддержка високосного года, вам нужно только манипулировать этой частью выражения:
(19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]))
Надеюсь, это очень помогло вам
Ответ 11
Другой ответ, который проверяет день (dd) в зависимости от месяца (мм) и года (гггг) (т.е. также проверяет 29 февраля в високосные годы) и позволяет использовать годы от 0001 до 9999 (0000 в год, недействительный к григорианскому календарю)
^(?:(?:(?:0[1-9]|[12]\d|3[01])/(?:0[13578]|1[02])|(?:0[1-9]|[12]\d|30)/(?:0[469]|11)|(?:0[1-9]|1\d|2[0-8])/02)/(?!0000)\d{4}|(?:(?:0[1-9]|[12]\d)/02/(?:(?!0000)(?:[02468][048]|[13579][26])00|(?!..00)\d{2}(?:[02468][048]|[13579][26]))))$
Ответ 12
Здесь я написал один для dd/mm/yyyy
, где разделитель может быть одним из -.,/
year range 0000-9999
.
Он относится к високосные годы и предназначен для ароматизаторов регулярных выражений, которые поддерживают взгляды, захватывающие группы и обратные ссылки. НЕ действует для d/m/yyyy
. При необходимости добавьте дополнительные разделители в [-.,/]
^(?=\d{2}([-.,\/])\d{2}\1\d{4}$)(?:0[1-9]|1\d|[2][0-8]|29(?!.02.(?!(?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)\d{2}(?:[02468][048]|[13579][26])))|30(?!.02)|31(?=.(?:0[13578]|10|12))).(?:0[1-9]|1[012]).\d{4}$
Тест в regex101; как строка Java:
"^(?=\\d{2}([-.,\\/])\\d{2}\\1\\d{4}$)(?:0[1-9]|1\\d|[2][0-8]|29(?!.02.(?!(?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)\\d{2}(?:[02468][048]|[13579][26])))|30(?!.02)|31(?=.(?:0[13578]|10|12))).(?:0[1-9]|1[012]).\\d{4}$"
поясняет:
(?x) # modifier x: free spacing mode (for comments)
# verify date dd/mm/yyyy; possible separators: -.,/
# valid year range: 0000-9999
^ # start anchor
# precheck xx-xx-xxxx,... add new separators here
(?=\d{2}([-.,\/])\d{2}\1\d{4}$)
(?: # day-check: non caturing group
# days 01-28
0[1-9]|1\d|[2][0-8]|
# february 29d check for leap year: all 4y / 00 years: only each 400
# 0400,0800,1200,1600,2000,...
29
(?!.02. # not if feb: if not ...
(?!
# 00 years: exclude !0 %400 years
(?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)
# 00,04,08,12,...
\d{2}(?:[02468][048]|[13579][26])
)
)|
# d30 negative lookahead: february cannot have 30 days
30(?!.02)|
# d31 positive lookahead: month up to 31 days
31(?=.(?:0[13578]|10|12))
) # eof day-check
# month 01-12
.(?:0[1-9]|1[012])
# year 0000-9999
.\d{4}
$ # end anchor
Также см. часто задаваемые вопросы SO Regex; Пожалуйста, дайте мне знать, если это не удастся.
Ответ 13
Я работаю с API, который принимает только формат MM/DD/YYYY. Я не мог найти ни одного другого сообщения, которое бы действительно високосного года, а Ofir answer, поэтому я изменил его и повторно разместил его здесь для тех, кому это может понадобиться.
/^(?:(?:(?:0[13578]|1[02])(\/)31)\1|(?:(?:0[1,3-9]|1[0-2])(\/)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:02(\/)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/)(?:0[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/
Ответ 14
((((0[13578]|1[02])\/(0[1-9]|1[0-9]|2[0-9]|3[01]))|((0[469]|11)\/(0[1-9]|1[0-9]|2[0-9]|3[0]))|((02)(\/(0[1-9]|1[0-9]|2[0-8]))))\/(19([6-9][0-9])|20([0-9][0-9])))|((02)\/(29)\/(19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]|2[048])))
будет проверять формат MM/DD/YYYY
с 1960
до 2028
если вам нужно продлить поддержку високосного года, добавьте
19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]|2[048]|3[26]|4[048])))
это также работает
^((((0[13578]|1[02])[/](0[1-9]|1[0-9]|2[0-9]|3[01]))|((0[469]|11)[/](0[1-9]|1[0-9]|2[0-9]|3[0]))|((02)([/](0[1-9]|1[0-9]|2[0-8]))))[/](19([6-9][0-9])|20([0-9][0-9])))|((02)[/](29)[/](19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]|2[048])))
если вы можете изменить формат mm-dd-yyyy
, чем заменить [/]
на [-]
также проверьте онлайн http://regexr.com/
Ответ 15
Для даты MM/DD/YYYY вы можете использовать
^((((0[13578])|([13578])|(1[02]))[\/](([1-9])|([0-2][0-9])|(3[01])))|(((0[469])|([469])|(11))[\/](([1-9])|([0-2][0-9])|(30)))|((2|02)[\/](([1-9])|([0-2][0-9]))))[\/]\d{4}$|^\d{4}$
Он проверяет правильные дни и моли.
Помните, что вы можете проверить свое регулярное выражение на
regex101
который я рекомендую:)
Удачи!
Ответ 16
^(((([13578]|0[13578]|1[02])[-](0[1-9]|[1-9]|1[0-9]|2[0-9]|3[01]))|(([469]|0[469]|11)[-]([1-9]|1[0-9]|2[0-9]|3[0]))|((2|02)([-](0[1-9]|1[0-9]|2[0-8]))))[-](19([6-9][0-9])|20([0-9][0-9])))|((02)[-](29)[-](19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]|2[048])))
это регулярное выражение будет проверять даты в формате:
12-30-2016 (mm-dd-yyyy) или 12-3-2016 (мм-d-yyyy) или
1-3-2016 (m-d-yyyy) или 1-30-2016 (m-dd-yyyy)