Comments & Discussion
protected function startDate(): Attribute
{
return Attribute::make(
set: fn ($value) => Carbon::createFromFormat('d/m/Y', $value)->format(format: 'Y-m-d'),
get: fn ($value) => Carbon::createFromFormat('Y-m-d', $value)->format(format: 'd/m/Y'),
);
}
When executing above code, i am getting below error :
Carbon \Exceptions \InvalidFormatException
The separation symbol could not be found Unexpected data found. Trailing data
Please guide
Tried following Steps after installation of laravel project with starter kit : breeze
Step 1 : added birth_date in users table
Schema::create('users', function (Blueprint $table) {
...
$table->date('birth_date')->nullable();
--
});
Step 2: added birth_date in User model
protected $fillable=[...'birth_date'];
Step 3: added method in User Model for accessor and mutator
protected function birthDate(): Attribute
{
return Attribute::make(
get: fn ($value) => Carbon::createFromFormat('Y-m-d', $value)->format(format: 'm/d/Y'),
set: fn ($value) => Carbon::createFromFormat('m/d/Y', $value)->format(format: 'Y-m-d'),
);
}
Step 4 : modified resources\views\auth\register.blade.php to add birth_date
<div class="mt-4">
<x-input-label for="birth_date" :value="__('birth_date')" />
<x-text-input id="birth_date" class="block mt-1 w-full" type="date" name="birth_date" :value="old('birth_date')" required autocomplete="birthdate" />
<x-input-error :messages="$errors->get('birth_date')" class="mt-2" />
</div>
Step 5 : after migration & run project, when tried to register user by clicking on Register button, following error occured
Carbon \Exceptions \ InvalidFormatException
The separation symbol could not be found Unexpected data found. Trailing data
When I comment below method everthing is fine and birth_date get saved in database
// protected function birthDate(): Attribute{ // .... // }
Also note, it works under tinker but not on Form
Hope you understood the problem. please guide on this.
That's exactly the point, your're answering your own question: "it works under tinker but not on form".
Which means that your FRONT-END date picker does not give the correct date format.
That x-text-input type="date" should provide the dates in the format you provided.
But also, I see you were mentioning the format dd-mm-yyyy earlier, but in the code of this latest comment, in the set part, I see createFromFormat('m/d/Y'), maybe that's the reason? m/d/Y instead of d/m/Y?
Hi Povilas, Thanks for quick response.
Please note, that the date format seen in form is based on local system date setting.
By keeping system date format either dd-mm-yyyy or mm-dd-yyyy error does not change.
Also tried after changing createFromFormat('m/d/Y') to createFromFormat('d/m/Y'). Error remains same.
Carbon\Exceptions \InvalidFormatException
The separation symbol could not be found Unexpected data found. Trailing data
My objective is to set date entry format as dd/mm/yyyy, irrespective of user's system date.
I think that you are mixing some things up. Let's clear them out and hopefully understand the issue better:
- You are using
input type=datewhich is controlled by the browser. You cannot decide the date format there, it is dependant on the format that the browser has. If you need to change the format displayed there to ignore user settings - you need to use a 3rd party JS datetime picker. - You are assuing that the date is coming to you in
m/d/Yformat, but in reality it is not. Please dump the request to see what format the date returns for you (probably like Y-m-d) - Your date is nullable, yet your GET method does not account for that. You are trying to parse a date from null. Add an if condition to only parse if the value is there, and skip it if there's no value.
Hope these will help you understand what's going on!
Thanks Modestas, I changed the code to skip null value as follows :
protected function birthDate(): Attribute
{
return Attribute::make(
get: fn ($value) => Carbon::createFromFormat('Y-m-d', $value)->format(format: 'd/m/Y'),
set: $this->value ? fn ($value) => Carbon::createFromFormat('d/m/Y', $value)->format(format: 'Y-m-d') : null,
);
}
But I could not figureout the practical application of the date mutator and accessor example shown by Povilas
By adding condition to setter, error got eliminated, which was seen on form saving. So far, there is no error on getter, so condition not added.
I am in learning phase.
I want to show birth date on form in dd/mm/yyyy irrespective of browser format. Can it be done using getter ?
In single case (get OR set attribute) the old way is simpler, more clear and easier to read. However in mixed case the new way looks more logical and better.
I like the new way better