Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

dezgo's avatar

Date handling - Carbon and formatting

I've done quite a bit of googling, and experimenting with my codebase, but I can't seem to get the date handling right. I simply want to store my dates in my model as Carbon instances, so I have them in the $dates variable. I have my preferred dateFormat, and the casts variable, apparently to get data entered using the dateFormat specified, automatically converted back to Carbon instances?

protected $dateFormat = 'd-m-Y';
protected $dates = ['invoice_date', 'due_date', 'created_at', 'updated_at', 'deleted_at'];
protected $casts = ['invoice_date' => 'date', 'due_date' => 'date'];

But when I show my view, I get an Exception in Carbon.php line 425 - 'The separation symbol could not be found' in the createFromFormat function

public static function createFromFormat($format, $time, $tz = null)
    {
        if ($tz !== null) {
            $dt = parent::createFromFormat($format, $time, static::safeCreateDateTimeZone($tz));
        } else {
            $dt = parent::createFromFormat($format, $time);
        }

        if ($dt instanceof DateTime) {
            return static::instance($dt);
        }

        $errors = static::getLastErrors();
        throw new InvalidArgumentException(implode(PHP_EOL, $errors['errors']));
    }

The error happens because the above function receives $format = 'd-m-Y', $time = '2016-04-08 00:00:00', so it can't convert it.

The view is using form-model binding, and I'm converting the input to an array to get the dates to be formatted correctly:

!! Form::model($invoice->toArray(), ['method' => 'GET', 'url' => 'invoice/'.$invoice->id.'/edit']) !!}

I had a workaround before where I forced my model to always return my dates as a formatted string in my preferred format using an accessor, but that doesn't seem right. Isn't that was the $dateFormat property does?

0 likes
8 replies
dezgo's avatar

Hey Prez. The thing is I'm not calling that createFromFormat() function directly, it's being called through the Laravel framework when I do the ->toArray() call in the Form. I suppose if I set $format = Y-m-d H:i:s it will work, but I wanted to use the d-m-Y format.

jekinney's avatar

@dezgo What is the Column type in the database?

fyi, you only NEED to any dates not included with timestamps().

protected $dates = ['invoice_date', 'due_date'];

when displaying dates from the db:

$model->invoice_date->toDateString();       // YYYY-MM-DD
$model->invoice_date->toFormattedDateString(); //Dec 25, 1975

To accept the date from a form and put into database:

Carbon::createFromFormat('Y-m-d',  $val); // Notice the capital Y not lowercase and the position of each is important. Your code above has it backwards.

Use HTML instead of form helpers... much faster and simpler. Why toArray(), the form model should accept an object not an array as far as I remember (l4.0 was last time i touched form helpers).

dezgo's avatar

@jekinney Column type is datetime. And yep good pickup on the $dates, I noticed that today.

The thing is I'm using form-model binding so didn't want to override that and explicitly specify the field value. The Form helper accepts an array or object. When using an array it'll then convert the date based on that dateFormat field.

But I couldn't get that working, so I'm currently using Carbon's setToStringFormat function as per balping's answer at http://stackoverflow.com/questions/31735594/laravel-dates-on-form-model-binding/31737184#31737184 before showing any form with a date on it. Not ideal.

Your suggestions are good, I think I might have to forget about using the form-model binding though to use them.

1 like
Qlic's avatar

I'm not really sure what you are trying to do here, but if your data is already a carbon instance (as stored in the DB), than there is no need to use createFromFormat, instead use your $dateFormat variable to display it in the way you want like:

$data->created_at->format($dateFormat);
rsands's avatar

Accessors and mutators will handle the conversion to and from a specific format for display and settings to database

Snapey's avatar

There seems to be way too much work going on here?

I just create a dateTime column in the database - (this does not store in 'carbon format')

then create an accessor that converts the dateTime field into a Carbon instance ( I guess this is what adding it to the $dates field does)

in any view or elsewhere then just know that the field is a carbon object and use it directly or apply formatting for the situation.

dezgo's avatar

Thanks @Snapey . I agree this should be simple. I'm just wanting to do that standard use-case. Store in db as a date, manipulate it in the model as a Carbon instance, and display it to the user as a formatted date, preferably in the format d-m-Y.

The issue is with the form-model binding, it's automatically populated, you don't manually specify the field so there's no opportunity to format it. I thought that's where the $dateFormat protected variable came into it.

I'm now unsure how to use that $dateFormat property. The code says this:

/**
 * The storage format of the model's date columns.
 *
 * @var string
 */
protected $dateFormat;

So maybe that variable has nothing to do with presentation?

Snapey's avatar

I've never tried to use it to return a default format, I only consider its use for interpretation of dates passed to the model.

In the Form class, when you specify the date field, can you not add the formatting there? How are you handling the date on the form, is it just a html5 native date picker?

Form::date('due_date',$model->due_date->format('d-M-Y'));

I've not used form for a few years so I'm not sure exactly.

Please or to participate in this conversation.