diff --git a/lib/JSV/Validator.pm b/lib/JSV/Validator.pm index 8a6c9ab..63fb390 100644 --- a/lib/JSV/Validator.pm +++ b/lib/JSV/Validator.pm @@ -68,7 +68,11 @@ sub new { reference => JSV::Reference->new, formats => +{ 'date' => sub { - ($_[0] =~ /\A\d{4}-\d{2}-\d{2}\z/); + my ($year, $month, $mday) = ($_[0] =~ /\A(\d{4})-(\d{2})-(\d{2})\z/) or return; + return 0 if $month > 12 || $month < 1 || + $mday > [31,29,31,30,31,30,31,31,30,31,30,31]->[$month-1] || + ($mday == 29 && $month == 2 && !($year % 4 == 0 && ($year % 100 != 0 || $year % 400 == 0))); + return 1; }, 'date-time' => sub { # RFC3339 diff --git a/t/issues/00049_date_format.t b/t/issues/00049_date_format.t new file mode 100644 index 0000000..c7624c3 --- /dev/null +++ b/t/issues/00049_date_format.t @@ -0,0 +1,24 @@ +BEGIN { $ENV{PERL_JSON_BACKEND} = 'JSON::XS' } +use strict; +use warnings; +use Test::More; +use Test::Requires qw(JSON::XS); +use JSV::Validator; + +my $v = JSV::Validator->new(environment => 'draft4'); +my $schema = { + type => 'string', + format => 'date', +}; + +for ("2017-02-28", "2018-02-28", "2020-02-29") { + is ($v->validate($schema, $_), 1, "valid: $_"); +} + +for ("I don't trust stairs. They're always up to something.", "2014-56-78", "2017-02-29", "2018-02-29", "2018-02-30", "2019-02-29") { + is ($v->validate($schema, $_), 0, "invalid: $_"); +} + +done_testing; + +1;