Tahmid Rafi
Tahmid Rafi

Reputation: 469

How to validate an input date from individual day, month, year input in Laravel 5

I have a user registration form which takes input birth day split in 3 different input fields i.e. day, month, year

{!! Form::selectMonth('month', null) !!}
{!! Form::selectRange('day', 1, 31, null) !!}
{!! Form::selectYear('year', Carbon\Carbon::now()->year, (new Carbon\Carbon('100 years ago'))->year, null) !!}

In the backend I have modified the Registrar.php/validator() to check the input date is a valid one:

public function validator(array $data) {

    $data['date_of_birth'] = Carbon::create($data['year'], $data['month'], $data['day'], 0, 0, 0)->toDateString();
    $current_year          = Carbon::now()->year;
    $hundred_years_ago     = (new Carbon("100 years ago"))->year;

    return Validator::make($data, [
        'year'          => 'Required|Integer|Between:'.$hundred_years_ago.','.$current_year,
        'month'         => 'Required|Integer|Between:1,12',
        'day'           => 'Required|Integer|Between:1,31',
        'date_of_birth' => 'Required|Date',
    ]);

}

But surely it doesn't check if an invalid date was provided. If the user provides an invalid date such as 31st February, 1982, the Carbon::create() transforms the date to 3rd March, 1982 which turns out to be a valid one.

If I want to filter this type of date input what do I need to do? I do believe this is likely a very common requirement for those who don't use any datepicker of some sort.

Upvotes: 2

Views: 9164

Answers (1)

pespantelis
pespantelis

Reputation: 15382

Laravel using the strtotime and checkdate functions to validate a date.

How the validateDate function of Laravel works? An example:

strtotime('30-2-2015'); // returns a timestamp
checkdate(2, 30, 2015); // returns false
// laravel raises an error

Therefore, the value of $data['date_of_birth'] should be a string in a particular format.

public function validator(array $data)
{
    $data['date_of_birth'] = $data['day'].'-'.$data['month'].'-'.$data['year'];
    $current_year          = Carbon::now()->year;
    $hundred_years_ago     = (new Carbon("100 years ago"))->year;

    return Validator::make($data, [
        'year'          => 'Required|Integer|Between:'.$hundred_years_ago.','.$current_year,
        'date_of_birth' => 'Required|Date',
    ]);
}

Also you can ignore the validation of day and month, since the date will be validated.

Upvotes: 2

Related Questions