Как я могу проверить действительный формат даты в Perl? - PullRequest
1 голос
/ 13 мая 2009


Я получаю поле даты из базы данных в одной из моих переменных, в настоящее время я использую следующий код, чтобы проверить, находится ли дата в формате "гггг-мм-дд"

if ( $dat =~ /\d{3,}-\d\d-\d\d/ )

Мой вопрос, есть ли лучший способ сделать это.

Большое спасибо

Ответы [ 7 ]

5 голосов
/ 13 мая 2009

Репозиторий регулярных выражений OWASP для проверки в формате США с поддержкой високосных годов:

^ (:( :( ?: 0 [13578] | 1 [02]??)? (/ | - |.) 31) \ 1 | (:( ?: 0 [1,3-9 ] | 1 [0-2]) (/ | - |.??) (?: 29 | 30) \ 2)) (:( ?: 1 [6-9] | [2-9] \ d) \ д {2}) $ | ^ (?: 0 2 (/ | - |?.) (? :( :( ?: 1 [6-9] | [2-9] \ д)? 29 \ 3 ( ?: 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}) $

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

^\d{4}-\d{1,2}-\d{1,2}$
4 голосов
/ 14 мая 2009

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

Но тот недостаток, что он будет принимать недействительные даты, такие как 2009-02-30. Опять же, если вы обрабатываете даты, которые успешно превратились в поле с типом даты в БД, вы должны быть в безопасности.

Более надежный подход заключается в использовании одного из множества модулей даты / времени из CPAN. Возможно, Date :: Manip был бы хорошим выбором, и, в частности, проверьте функцию ParseDate ().

http://metacpan.org/pod/Date::Manip

3 голосов
/ 13 мая 2009

Как насчет

/\d{2}\d{2}?-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/
2 голосов
/ 13 мая 2009

\ d может совпадать с цифрами на других языках. И действительно ли YYY действительный год? Если это должно быть четыре цифры, тире, две цифры, тире, две цифры, я бы предпочел /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/ или /^[12][0-9]{3}-[0-9]{2}-[0-9]{2}$/. Помните о пробелах вокруг подходящей строки.

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

1 голос
/ 12 июля 2016

Лучшим и легким решением является использование подпрограммы Date :: Calc * check_date , вот пример:

use strict;
use warnings
use Date::Calc qw[check_date];

## string in YYYY-MM-DD format, you can have any format
## you like, just parse it
my @dt_dob = unpack("A4xA2xA2",$str_dob_date);

unless(check_date(@dt_dob)) {
    warn "Oops! invalid date!";
}

Надеюсь, это было полезно: -)

1 голос
/ 13 мая 2009

Ну, вы можете начать с:

/\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|30|31)/ 
0 голосов
/ 15 мая 2009

Я бы настоятельно рекомендовал ПРОТИВ написать собственное регулярное выражение для этого. Разбор даты и времени прост, но есть некоторые хитрые аспекты, и эта проблема решалась сотни раз. Вам не нужно разрабатывать, писать и отлаживать еще одно решение.

Если вам нужно регулярное выражение, лучшим решением, вероятно, будет использование моего плагина Regexp :: Common :: time для модуля Regexp :: Common. Вы можете указать простое или сложное, жесткое или нечеткое сопоставление даты и времени, и оно имеет очень обширный набор тестов.

Если вы просто хотите разобрать определенные форматы даты, вам лучше использовать один из множества плагинов для разбора / форматирования для превосходного модуля Дейва Рольски DateTime.

Если вы хотите проверить значения даты / времени после их сопоставления, я бы предложил мой модуль Time :: Normalize.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...