Date validation - How localize/translate strings "today" and "tomorrow"
Asked Answered
E

4

21

In my model I defined a few validation rules for date fields using before and after:

'birth_date' => 'required|date|before:today|after:01-jan-1920',
'another_date' => 'required|date|before:tomorrow|after:01-jan-1990',

The validation works fine, however I can't figure out how to translate the strings today and tomorrow on the validation message.

In the validation.php language file the after and before messages are localizable, however the :date part of the message is still displaying the English version for today and tomorrow.

"after"            => "The :attribute must be a date after :date.",
"before"           => "The :attribute must be a date before :date.",

How could I localize those two words - today and tomorrow - in the validation message?

Ending answered 11/4, 2016 at 10:30 Comment(1)
Answers so far are only workarounds. What must we put in the resources/lang/whichever/validation.php to account for "today" and "tomorrow"?Enterprising
A
19

In short, add following code into resources/lang/whichever/validation.php

'values' => [
    // or whatever fields you wanna translate
    'birth_date' => [
        // or tomorrow
        'today' => '今天'
    ]
]

Explained:

https://github.com/laravel/framework/blob/7.x/src/Illuminate/Validation/Concerns/FormatsMessages.php#L319

/**
 * Get the displayable name of the value.
 *
 * @param  string  $attribute
 * @param  mixed  $value
 * @return string
 */
public function getDisplayableValue($attribute, $value)
{
    if (isset($this->customValues[$attribute][$value])) {
        return $this->customValues[$attribute][$value];
    }

    // the key we want
    $key = "validation.values.{$attribute}.{$value}";

    // if the translate found, then use it
    if (($line = $this->translator->get($key)) !== $key) {
        return $line;
    }

    if (is_bool($value)) {
        return $value ? 'true' : 'false';
    }

    return $value;
}
Aten answered 8/4, 2020 at 6:28 Comment(2)
Thanks! This was the best solution for me :)!Koumis
This is the best approach! Works great even with Laravel 11, thanks :)Inanna
S
3

You can use custom validation messages per field, either on validation language file or in your code itself: https://laravel.com/docs/5.2/validation#custom-error-messages

Let's simulate a controller validation to see how it works:

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;

class YourController extends Controller
{
    public function store(Request $request)
    {
        $rules = [
            'birth_date' => 'required|date|before:today|after:01-jan-1920',
        ];
        $messages = [
            'birth_date.before' => 'A data de nascimento deve ser uma data antes de hoje.', // "The birth date must be a date before today" in portuguese
        ];

        $this->validate($request, $rules, $messages);

        /* your stuff */
    }
}

You can also do that with form requests (which are even nicer), all you need to do is return your custom translated messages inside messages() method. :)

Sounding answered 28/6, 2016 at 8:3 Comment(0)
K
1

Use custom error messages.

$this->validate(
            $request,
            [
                'phone' => 'required|regex:/^(\d[\s-]?)?[\(\[\s-]{0,2}?\d{3}[\)\]\s-]{0,2}?\d{3}[\s-]?\d{4}$/i'
            ],
            [
                'regex' => 'You must enter a valid phone number.',
                'required' => 'You must enter a valid phone number.'
            ]
        );

Replace 'regex' and 'required' with 'before:today' and 'before:tomorrow' and replace with custom error messages.

Katalin answered 13/5, 2018 at 0:31 Comment(0)
R
0

It probably makes more sense to make some custom validations but I think you should be able to do this simply with Carbon:

$dt = new Carbon\Carbon();
$today = $dt->today();
$tomorrow = $dt->tomorrow();

    $rules = [
        ...
        'birth_date' => 'required|date|before:'.$today.'|after:01-jan-1920',
        'another_date' => 'required|date|before:'.$tomorrow.'|after:01-jan-1990'
    ];
Readability answered 28/6, 2016 at 2:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.