Формат проверки даты Grail для проверки правильности
В настоящее время я работаю в проекте Grails, и у меня возникла проблема с ограничениями совпадений в Grails. Мое поле должно принимать только строку с форматом даты, подобным этому:
10-25-2012 17:00
Возможно ли это в ограничении совпадений с помощью регулярных выражений? Мне всегда трудно фильтровать данные с помощью регулярных выражений, потому что это немного сбивает с толку.
4 ответа
Если это данные, почему бы не проверить их с помощью стандартного средства форматирования даты? Подобно:
static constraints = {
mydate validator: {
try {
Date.parse('MM-dd-yyyy hh:mma', it)
return true
} catch (ParseException e) {
return false
}
}
}
Кстати, в этом случае Date
может анализировать не очень допустимые даты (и преобразовать его в корректное значение, например, 15am
в 3pm
). Если вам нужен точно правильный формат, вы можете сравнить его с исходным значением:
static constraints = {
mydate validator: {
try {
Date date = Date.parse('MM-dd-yyyy hh:mma', it)
return Date.format('MM-dd-yyyy hh:mma', date) == it
} catch (ParseException e) {
return false
}
}
}
Или вы можете использовать SimpleDateFormat
вместо:
final static DateFormat DATEFORMAT = new SimpleDateFormat('MM-dd-yyyy hh:mma')
static constraints = {
mydate validator: {
try {
Date date = DATEFORMAT.parse(it)
return DATEFORMAT.format(date) == it
} catch (ParseException e) {
return false
}
}
}
Разве нет объекта Date, который вы можете использовать? Я не знаю, но я могу помочь вам с регулярным выражением:
Построить регулярное выражение несложно, особенно в вашем случае:
^\d{2}-\d{2}-\d{4} \d{2}:\d{2}[AP]M$
^
Соответствует началу строки
$
Соответствует концу строки
\d
это цифра
{2}
это квантификатор, который делает предыдущий символ требуется 2 раза
[AP]
класс персонажа, который соответствует A
или же P
Это регулярное выражение просто проверяет формат, а не если цифры представляют действительную дату или время! (например, 99-99-0000 35:61PM действителен)
Прочтите мой пост в блоге Что абсолютно каждый программист должен знать о регулярных выражениях для получения более краткой информации.
Попробуй это
\b(?:(?:(?:0?[469]|11)\-(?:0?(?:[1-9]|[12][0-9])|30)\-(?:1[7-9][0-9]{2}|200[0-9]|201[0-2]))|(?:(?:0?[13578]|1[02])\-(?:0?(?:[1-9]|[12][0-9])|3[01])\-(?:1[7-9][0-9]{2}|200[0-9]|201[0-2]))|(?:(?:0?2)\-(?:0?(?:[1-9]|1[0-9])|2[0-8])\-(?:1[7-9][0-9]{2}|200[0-9]|201[0-2]))) +(?:(?:(?:0?([0-9])|1[0-2])):(?:0?([0-9])|[1-5][0-9])(?:[AP]M))\b
или же
\b(?:(?:(?:0?[469]|11)\-(?:0?(?:[1-9]|[12][0-9])|30)\-(?:1[7-9][0-9]{2}|200[0-9]|201[0-2]))|(?:(?:0?[13578]|1[02])\-(?:0?(?:[1-9]|[12][0-9])|3[01])\-(?:1[7-9][0-9]{2}|200[0-9]|201[0-2]))|(?:(?:0?2)\-(?:0?(?:[1-9]|1[0-9])|2[0-9])\-(?:1[7-9][0-9]{2}|200[0-9]|201[0-2]))) +(?:(?:(?:0?([0-9])|1[0-2])):(?:0?([0-9])|[1-5][0-9])(?:[AP]M))\b
Примечание: у двух шаблонов есть общее ограничение, что он будет соответствовать недопустимому dates
если month
является february
, Условные операторы if-else принимаются в некоторых разновидностях RegEx, но для арифметических операций таких функций не существует. Может быть, в далеком или ближайшем будущем это может быть реализовано в некоторых разновидностях RegEx, но я думаю, что это не тот случай, чем в принципе является RegEx.
- Первый шаблон не найдет дату больше
28
с февраля месяца. И это никогда не будет соответствовать ни одной недействительной дате. - Второй точно такой же, как указано выше, но для него число
29
,
И мне хорошо известно о том, что эту проблему невозможно полностью решить с помощью RegEx.
Попробуй это: ^(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])-((?:19|20)\d\d) ([0-1]?[0-9]|2[0-4]):([0-5][0-9])(?::([0-5][0-9]))?(AM|PM)$
^ Start of string
(0[1-9]|1[012]) Month
-
(0[1-9]|[12][0-9]|3[01]) Day
-
((?:19|20)\d\d) Year
([0-1]?[0-9]|2[0-4]) HH
:
([0-5][0-9]) MM
(?::([0-5][0-9]))? optional :SS
(AM|PM)
$ End of string
Он фиксирует месяц, день, год, часы, минуты, секунды и AM/PM.
Редактировать: Как указывает Викас, он не проверяет, сколько дней в месяце может быть.