Laravel: full date validation guide

When it comes to date validation, Laravel covers most date validation cases. Of course, sometimes you will need to install some additional packages to cover specific validation, but overall the batch of native Laravel validation rules will be enough. In this article, I will overview the most popular date validation cases.

Table of Contents

How to validate date in Laravel?

If you need to check the input for a valid date then you should use the date validator.

$request->validate(   
    'date_field' => 'date' 
);   

What does it mean by “valid date”? What is under the hood of the date validator? Let’s dive into it. This validator checks if the given value is a string or numeric, then passes the value to the PHP strtotime() function and checks if this function can parse the value into Unix timestamp. If the result of these checks is positive then the validator parses the value with the PHP date_parse() function and checks if the parsed value is a valid Gregorian date using the PHP checkdate() function. In case of the given value is an instance of DateTimeInterface (DateTime or DateTimeImmutable objects) validator uses an early return with a positive validation result.

public function validateDate($attribute, $value)
{
    if ($value instanceof DateTimeInterface) {
        return true;
    }

    try {
        if ((! is_string($value) && ! is_numeric($value)) || strtotime($value) === false) {
            return false;
        }
    } catch (Exception $e) {
            return false;
    }

    $date = date_parse($value);

    return checkdate($date['month'], $date['day'], $date['year']);
}

How to validate specific date and time in Laravel?

When you need to validate the input field for a specific date or time then you should use the date_equals validator.

$request->validate(   
    'date_field' => 'date_equals:11/30/2022' 
);   

Here is an example with a specific time validation:

$request->validate(   
    'date_field' => 'date_equals:15:00' 
);   

And one more example with a specific date and time:

$request->validate(   
    'date_field' => 'date_equals:11/30/2022 15:00' 
);   

How to validate date range in Laravel?

Sometimes you need to check the date input value for a specified date range or to check if the input value is after or before the specific date. To do that, you can specify min and max dates with these Laravel validators: before, before_or_equals, after, after_or_equals.

Here is an example of date validation using the before validator:

$request->validate(   
    'date_field' => 'before:11/30/2022' 
);   

And of course, you can specify both the date and the time:

$request->validate(   
    'date_field' => 'before_or_equals:11/30/2022 15:00' 
);  

Or just the time will work too:

$request->validate(   
    'date_field' => 'after:15:00' 
);  

To validate date range you can use both before/before_or_equals and after/after_or_equals validators:

$request->validate(   
    'date_field' => 'after:11/01/2022|before:11/30/2022' 
);  
$request->validate(   
    'date_field' => 'after_or_equals:11/01/2022|before_or_equals:11/30/2022' 
);  

When you have three fields – the first one is for the start date, the second one is for the end date and you want to check if the third input value is between the start date and end date, then in before/before_or_equals/after/after_or_equals validators you can specify the start date and the end date input names. Here is an example:

$request->validate(   
    'start_date_field' => 'date', 
    'end_date_field' => 'date', 
    'date_field' => 'after:start_date_field|before:end_date_field', 
);  

How to validate date format in Laravel?

If a user must provide a date in a specific format then you can validate it using the date_format validator.

$request->validate(   
    'date_field' => 'date_format:m/d/Y' 
);  

This validator supports all formats supported by PHP’s DateTime class createFromFormat() method.

You should not use date together with date_format because the second one has a check for a valid date. Let’s see how it works.

if (! is_string($value) && ! is_numeric($value)) {
    return false;
}

foreach ($parameters as $format) {
    $date = DateTime::createFromFormat('!'.$format, $value);

    if ($date && $date->format($format) == $value) {
        return true;
    }
}

Laravel tries to create a DateTime object from a specified format. If the DateTime object was created successfully, then the validator compares that object formatted in a specified format with the given value. If the user entered not valid Gregorian date but its format is the same as specified, then createFromFormat() method will create another date recalculated by the Gregorian calendar and will not pass this check:

$date->format($format) == $value

How to validate time in Laravel?

To validate time you should also use the date_format validator and specify any time format you need. For example:

$request->validate(   
    'date_field' => 'date_format:H:i:s' 
);  

How to validate time in AM/PM format in Laravel?

The AM or PM format is supported by PHP’s DateTime class, so you can easily validate it using the date_format validator:

$request->validate(   
    'date_field' => 'date_format:H:i:s A' 
);  

How to pass date validation if input value is null in Laravel?

When you need to pass data validation if a date field is empty and validate it only if the user entered something into it, then you should use the nullable validator:

$request->validate(   
    'date_field' => 'date|nullable'
);  

How to validate timezone in Laravel?

You can check if the given string is a timezone supported by PHP using the timezone validator. This validator simply checks if the given string is in the array returned by the timezone_identifiers_list() PHP function. Here is an example:

$request->validate(   
    'timezone_field' => 'timezone' 
);  

How to validate Unix timestamp in Laravel?

There are no validators to validate a Unix timestamp in Laravel. But we can think about what type the Unix timestamp really is. It is an unsigned integer. To validate an unsigned integer we can check if a value is an integer and if it is greater than zero. So we can use integer and min validators:

$request->validate(   
    'timestamp_field' => 'integer|min:1' 
);  

How to validate date if it has specific minutes?

Sometimes we need to check if the date has specific minutes. For example, we have two dates: 2022-11-11 09:15 and 2022-11-11 09:30. And we need to check if the date has the 15th minute or the 45th minute. So in this case the first date will be valid, and the second will be not valid. To validate the date in this way you need to install the vdhicts/laravel-validation-rules package with the Composer command:

composer require vdhicts/laravel-validation-rules

And then use the DateHasSpecificMinutes validation rule. The default date format is Y-m-d H:i, so if your date is in a different format then pass it as a second argument. Here are examples:

$request->validate(   
    'date_field' => [new DateHasSpecificMinutes([15, 45])]
);  

Or if you use are not using a default date format:

$request->validate(   
    'date_field' => [new DateHasSpecificMinutes([15, 45], 'm/d/Y H:i:s')]
);  

How to validate date against ISO 8601 standard in Laravel?

Which date is that: 11/01/12? November 11, 2012, or January 11, 2012, or January 12, 2011? It depends on which date format is used. It can be a problem when systems that communicate with each other use different date formats. That’s why ISO 8601 standard was created.

To validate date against ISO 8601 standard you can use penance316/laravel-iso8601-validator package. To install it run the Composer command:

composer require "penance316/laravel-iso8601-validator"

Then you should add the required validator to the boot method of app/Providers/AppServiceProvider.php.

Validator::extend('iso_date', 'Penance316\Validators\IsoDateValidator@validateIsoDate');

Then add a validation error message to resources/lang/en/validation.php:

'iso_date' => 'The :attribute must be a valid ISO8601 string.',

And add date and iso_date validators to your date validation rules:

$request->validate(   
    'date_field' => 'date|iso_date'
);