Carbon (laravel) deal with invalid date
Asked Answered
S

5

25

I have a quite simple problem.. I use the Carbon::parse($date) function with $date = '15.15.2015'. Of course it can not return a valid string because there is no 15th month. But how can i "ignore" the error message? Great would be something like

if (Carbon::parse($date) != error) Carbon::parse($date);
else echo 'invalid date, enduser understands the error message';
Solidstate answered 19/10, 2017 at 11:31 Comment(0)
S
15

Pass Laravel's validation before use it. Create a validator like this:

     protected function validator(array $data)
{
    //$data would be an associative array like ['date_value' => '15.15.2015']
    $message = [
        'date_value.date' => 'invalid date, enduser understands the error message'
    ];
    return Validator::make($data, [
        'date_value' => 'date',
    ],$message);
}

And call him right before use your date:

$this->validator(['date_value' => $date])->validate();
// $this->validator(request()->all())->validate(); you can pass the whole request if fields names are the same

Carbon::parse($date);

You can add all your desired fields to validator and apply multiple validations handling every message or using the default message. This would be the way if you are validating User's input

Slight answered 19/10, 2017 at 11:43 Comment(3)
Thanks! Where do i put the protected function?Solidstate
Inside the Controller which receives the $date or whatever file you want to use to validate incoming request / data. Remember to use: use Illuminate\Support\Facades\Validator;Slight
Thanks a lot! Yeah, got the message and looked it up myself.. It works, thank you very much!Solidstate
S
45

You can catch the exception raised by Carbon like this:

try {
    Carbon::parse($date);
} catch (\Exception $e) {
    echo 'invalid date, enduser understands the error message';
}

Later edit: Starting with Carbon version 2.34.0, which was released on May 13, 2020, a new type of exception is being thrown: Carbon\Exceptions\InvalidFormatException

So if you're using a newer version of Carbon, you can actually do this more elegantly

try {
    Carbon::parse($date);
} catch (\Carbon\Exceptions\InvalidFormatException $e) {
    echo 'invalid date, enduser understands the error message';
}

Thank you Christhofer Natalius for pointing this out!

Sterne answered 19/10, 2017 at 11:40 Comment(5)
You should include it wherever you want to validate the date & show the error message, that depends on what else are you doing on that request. I'd need your entire controller function in order to provide a more helpful answer.Sterne
you shouldnt catch exceptions as generic as this (\Exception), there might be underlying programming errors you miss otherwiseEugeneeugenia
Fair enough. What exception should I catch instead? Oh wait, the DateTime constructor only throws generic exceptions. At least do your research before interjecting with useless comments & downvoting a perfectly valid answer.Sterne
Now we can use Carbon\Exceptions\InvalidFormatException, idk since when this exception exists.Highsounding
There are instances where this function does not work properly. For example if $date = 30 then it takes it as a valid date but it is not a valid date. A valid date should be in the format "0000-00-00"Biel
S
15

Pass Laravel's validation before use it. Create a validator like this:

     protected function validator(array $data)
{
    //$data would be an associative array like ['date_value' => '15.15.2015']
    $message = [
        'date_value.date' => 'invalid date, enduser understands the error message'
    ];
    return Validator::make($data, [
        'date_value' => 'date',
    ],$message);
}

And call him right before use your date:

$this->validator(['date_value' => $date])->validate();
// $this->validator(request()->all())->validate(); you can pass the whole request if fields names are the same

Carbon::parse($date);

You can add all your desired fields to validator and apply multiple validations handling every message or using the default message. This would be the way if you are validating User's input

Slight answered 19/10, 2017 at 11:43 Comment(3)
Thanks! Where do i put the protected function?Solidstate
Inside the Controller which receives the $date or whatever file you want to use to validate incoming request / data. Remember to use: use Illuminate\Support\Facades\Validator;Slight
Thanks a lot! Yeah, got the message and looked it up myself.. It works, thank you very much!Solidstate
S
1

another solution would be to handle the exception globally.

  • in app/Exceptions/Handler.php
use Carbon\Exceptions\InvalidFormatException;
  • then in the render method check if an exception is thrown by Carbon
    if ($exception instanceof InvalidFormatException) {
            return response()->json([
                'status' => 'fail',
                'data' => [
                    'message' => 'Invalid date formate!'
                ]
            ], 400);
        }
Sola answered 10/12, 2020 at 12:18 Comment(0)
A
0

Try this

$birth_date = Carbon::createFromFormat('dmy', $birth_date_mark)->startOfDay();
if ($birth_date->format('dmy') !== $birth_date_mark) {
     throw new OperationException(trans('exception.invalid_birth_date'));
}
Azar answered 5/10, 2020 at 14:14 Comment(0)
D
0

Both try...catch... and validator is good. Sam's answer is good too.

In Laravel 8, I use following code:

// app/Exceptions/Handler.php

use Carbon\Exceptions\InvalidFormatException;

public function register()
{
    $this->renderable(function (InvalidFormatException $e, $request) {
        return response()->json([
            'message' => 'Invalid date format!.'
        ], 400);
    });
}

When InvalidFormatException thrown, Laravel will return http status 400 and json with message.

If you don't want to use try...catch... at every Carbon::parse() section, this is a good way to handle exception.

Diocese answered 9/2, 2022 at 4:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.