Skip to content

[11.x] Add Customizable Date Validation Rule with Flexible Date Constraints#53465

Merged
taylorotwell merged 15 commits into
laravel:11.xfrom
michaelnabil230:feature-add-validation-date
Jan 23, 2025
Merged

[11.x] Add Customizable Date Validation Rule with Flexible Date Constraints#53465
taylorotwell merged 15 commits into
laravel:11.xfrom
michaelnabil230:feature-add-validation-date

Conversation

@michaelnabil230

@michaelnabil230 michaelnabil230 commented Nov 10, 2024

Copy link
Copy Markdown
Contributor

This pull request introduces a new, customizable Date validation rule for Laravel. The Date rule simplifies date validation by offering chainable methods that allow for complex date requirements directly within the rule definition. This enhancement includes methods to specify date formats, enforce that dates are before or after specific dates (including "today"), and to ensure dates are on or before/after specified constraints.

With this addition, developers can create readable and flexible date validation rules without having to write multiple rules separately in the validation array.

Features

  • format($format): Specifies a date format for validation. Defaults to 'Y-m-d' if not specified.
  • afterToday(): Ensures the date is after today’s date.
  • beforeToday(): Ensures the date is before today’s date.
  • after($date): Ensures the date is after the specified date.
  • afterOrEqual($date): Ensure the date is on or after the specified date.
  • before($date): Ensures the date is before the specified date.
  • beforeOrEqual($date): Ensure the date is on or before the specified date.
  • afterOrEqual($date): Ensures the date is on or after the specified date.
  • beforeOrEqual($date): Ensures the date is on or before the specified date.
  • between($from, $to): Ensure the date is between two dates.
  • betweenOrEqual($from, $to): Ensure the date is between or equal to two dates.

Example Usage

Here is an example of how to use the Date rule in a Laravel form request:

use Illuminate\Validation\Rules\Date;

public function rules()
{
    return [
        'start_date' => [
            'required',
            new Date, // Defaults to validating the date
        ],
        'end_date' => [
            'required',
            (new Date)->after('start_date')->before('2025-01-01'), // Ensures end date is after start_date and before 2025-01-01
        ],
        'birth_date' => [
            'required',
            (new Date)->format('d/m/Y')->beforeToday(), // Validates birth_date is before today in 'd/m/Y' format
        ],
    ];
}

Benefits

This Date rule class:

  • Provides a clear, readable, and flexible way to define date validation rules.
  • Reduces redundancy in validation logic.
  • Ensures maintainable and concise validation definitions in complex date requirements.

@tontonsb

Copy link
Copy Markdown
Contributor

It's cool that it allows all the before/after/between validators to work with custom formats. Although in most cases I'd suggest normalizing the date format before validation instead.

It's not that cool that this seems to duplicate all the code. Is it worth maintaining two separate implementations of each rule?

@taylorotwell

Copy link
Copy Markdown
Member

Couple things come to mind. What about "before / after today" but inclusive of today? What about being about to pass Carbon / DateTime instances?

@taylorotwell taylorotwell marked this pull request as draft November 11, 2024 20:37
@michaelnabil230 michaelnabil230 marked this pull request as ready for review November 11, 2024 21:46
@michaelnabil230

Copy link
Copy Markdown
Contributor Author

Hi @taylorotwell,

Thanks for bringing this up! I’ve made a few adjustments based on your feedback:

Carbon/DateTime Support: Enhanced the formatDate() method to accept both Carbon and DateTime instances directly. Now, you can pass either of these instances, making it simpler to work with dynamically generated dates.

Let me know if this looks good or if there’s anything else you’d like to discuss. Thanks again for the insights!

@shaedrich

Copy link
Copy Markdown
Contributor

Although in most cases I'd suggest normalizing the date format before validation instead.

Unfortunately, normalization is out of scope here since, while FormRequests have a prepareForValidation() method, there currently is no declarative way to sanitize/normalize/cast/whatever the data before validation like the rules() method allows us for the data's validation.

@taylorotwell

taylorotwell commented Nov 18, 2024

Copy link
Copy Markdown
Member

How do we need to think about / validate hours / minutes / seconds with this PR? For example, what if I want to say a date / time combination is simply in the future, which would need second level validation?

@taylorotwell taylorotwell marked this pull request as draft November 18, 2024 22:07
@michaelnabil230 michaelnabil230 marked this pull request as ready for review January 11, 2025 00:51
@michaelnabil230

Copy link
Copy Markdown
Contributor Author

Hello @taylorotwell,

The PR doesn't require additional formatting. Based on my background, if you have any suggestions or ideas, feel free to share them, and I can add them if needed.

@shaedrich

Copy link
Copy Markdown
Contributor

Although in most cases I'd suggest normalizing the date format before validation instead.

Unfortunately, normalization is out of scope here since, while FormRequests have a prepareForValidation() method, there currently is no declarative way to sanitize/normalize/cast/whatever the data before validation like the rules() method allows us for the data's validation.

But you can with laravel-working-group/laravel-form-requests-improved

@taylorotwell taylorotwell merged commit 1049c03 into laravel:11.x Jan 23, 2025
@michaelnabil230 michaelnabil230 deleted the feature-add-validation-date branch January 23, 2025 15:14
@taylorotwell

Copy link
Copy Markdown
Member

@michaelnabil230 this rule seems totally broken. It returns a string like date|date_format potentially, but that does not work at all when placed in an array of validation rules.

@taylorotwell

Copy link
Copy Markdown
Member

#54353

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants