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

kylemilloy's avatar

Safari specific date input bug

I'm using <input type="date"> on the front-end of my app without poly-filling date inputs. This leaves Safari ignoring the type="date" bit and just giving me a regular text input. The problem here is that a user can then type in a date like "October 5, 2020" and it passes the date validation on my front-end component and in my form request but Carbon looks to choke on the value with an "Unexpected data found. The separation symbol could not be found Data missing" error from Carbon.

I've currently solved the issue by making an explicit set mutator on the model of my date field however I'm wondering if there's a more "Laravel"-esque way of doing this? I've also found that because I'm using faker in my tests to generate a custom_date I have to write a case to flip between Carbon's instance and parse methods to avoid throwing errors and it all just feels a little bloated.

class FormRequest
{
    public function rules() {
        return [ 'custom_date' => 'nullable|date|after:today'];
    }
}
class Model
{
    protected $dates = ['custom_date'];

    public function setCustomDateAttribute($date)
    {
        if ($date instanceof \DateTime) {
            return $this->attributes['custom_date'] = Carbon::instance($date)
                ->format('Y-m-d H:i:s');
        }

        return $this->attributes['custom_date'] = $date != null
            ? Carbon::parse($date)->format('Y-m-d H:i:s')
            : null;
    }
}
class Controller
{
    public function store(FormRequest $request)
    {
        Model::create($request->validated());
    }
}
0 likes
10 replies
kylemilloy's avatar

Thanks. I'm already doing this and it doesn't prevent people from still entering the date in whatever format they want, nor do I want to restrict people to only using a YYYY-MM-DD format.

My question is not "how do I fix this?" it's "Is there a 'Laravel' way to do what I'm already doing?" or is creating a mutator the best solve here? I'm sure I can't be the only one who has encountered this so I'm wondering if anyone knows of a method hidden deep in the API that coerces these values.

Tray2's avatar
Tray2
Best Answer
Level 73

I think you are stuck doing it in Carbon like you are doing. There might be some method in Carbon that can make it easier for you but I couldn't find any at first glance.

You could maybe do some reqular expressions to check the format

Something like

^(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$ 

Should cover most 'yyyy-mm-dd' and yyy/mm/dd

^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$.

Should cover dd-mm-yyy and dd/mm/yyyy

1 like
Cronix's avatar

use a js datepicker so they can't manually enter anything, and the format will always be consistent between browsers.

kylemilloy's avatar

Thanks @tray2 - I'll noodle with this some more and see what "feels" right. Appreciate the help.

@cronix - we've already explored this option but are not looking to polyfill the front-end as implementing a picker into the existing code-base, aligning the branding, removing the bloat and back filling with tests is a far larger ask than just making the coercion of values on the server-side more robust. Especially when this is a safari desktop only issue and our safari numbers are ~1%

Snapey's avatar

Much as I hate picky form inputs (eg credit card fields that don't allow spaces), in this case I would validate the field against a regex pattern and throw it back if not YYYY-MM-DD.

You then can guarantee that Carbon won't baulk at the presented format under any circumstances

It could be as simple as \d{4}-\d{2}-\d{2}

2 likes
kylemilloy's avatar

I (and more importantly, the UX team) are also not enamoured with the idea of picky inputs but I'll make a mental note that if that changes we can likely proceed with the regex route.

Tray2's avatar

You could always do the lazy thing and create three dropdowns year, month, day.

kylemilloy's avatar

Haha...yeah...except we already have three drop downs for hour, minute, meridiem... ;)

Please or to participate in this conversation.