Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle date input in Laravel

I'm working on an app that allows the user to edit several dates in a form. The dates are rendered in the European format (DD-MM-YYYY) while the databases uses the default YYYY-MM-DD format.

There are several ways to encode/decode this data back and forth from the database to the user, but they all require a lot of code:

  • Use a helper function to convert the date before saving and after retrieving (very cumbersome, requires much code)
  • Create a separate attribute for each date attribute, and use the setNameAttribute and getNameAttribute methods to decode/encode (also cumbersome and ugly, requires extra translations/rules for each attribute)
  • Use JavaScript to convert the dates when loading and submitting the form (not very reliable)

So what's the most efficient way to store, retrieve and validate dates and times from the user?

like image 350
Arne Avatar asked Jul 25 '14 23:07

Arne


People also ask

How to set date value in Laravel?

So, let's add these variables to config/app. return [ 'date_format' => 'm/d/Y', 'date_format_javascript' => 'MM/DD/YYYY', ]; And then, in Laravel, we can use this: Carbon::createFromFormat(config('app. date_format'), $value)->format('Y-m-d'); Carbon::parse($value)->format(config('app.

How do I change the date format in input?

To set and get the input type date in dd-mm-yyyy format we will use <input> type attribute. The <input> type attribute is used to define a date picker or control field. In this attribute, you can set the range from which day-month-year to which day-month-year date can be selected from.

How does laravel store dates?

You can use Carbon\Carbon::parse($date); and then pass the Carbon object to eloquent model.


2 Answers

At some point, you have to convert the date from the view format to the database format. As you mentioned, there are a number of places to do this, basically choosing between the back-end or the front-end.

I do the conversion at the client side (front-end) using javascript (you can use http://momentjs.com to help with this). The reason is that you may need different formats depending on the locale the client is using (set in the browser or in his profile preferences for example). Doing the format conversion in the front-end allows you to convert to these different date formats easily.

Another advantage is that you can then use the protected $dates property in your model to have Laravel handle (get and set) these dates automatically as a Carbon object, without the need for you to do this (see https://github.com/laravel/framework/blob/master/src/Illuminate/Database/Eloquent/Model.php#L126).

As for validation, you need can then use Laravel's built-in validation rules for dates, like this:

'date' => 'required|date|date_format:Y-n-j'
like image 74
lowerends Avatar answered Oct 25 '22 00:10

lowerends


While client-side is good for UX, it doesn't let you be sure, all will be good.

At some point you will need server-side validation/convertion anyway.

But here's the thing, it's as easy as this:

// after making sure it's valid date in your format
// $dateInput = '21-02-2014'

$dateLocale = DateTime::createFromFormat('d-m-Y', $dateInput);

// or providing users timezone
$dateLocale = 
   DateTime::createFromFormat('d-m-Y', $dateInput, new DateTime('Europe/London'));

$dateToSave = $dateLocale
           // ->setTimeZone(new TimeZone('UTC'))   if necessary
           ->format('Y-m-d');

et voila!


Obviously, you can use brilliant Carbon to make it even easier:

$dateToSave = Carbon::createFromFormat('d-m-Y', $dateInput, 'Europe/London')
        ->tz('UTC')
        ->toDateString(); // '2014-02-21'

Validation

You say that Carbon throws exception if provided with wrong input. Of course, but here's what you need to validate the date:

'regex:/\d{1,2}-\d{1,2}-\d{4}/|date_format:d-m-Y'

// accepts 1-2-2014, 01-02-2014
// doesn't accept 01-02-14

This regex part is necessary, if you wish to make sure year part is 4digit, since PHP would consider date 01-02-14 valid, despite using Y format character (making year = 0014).

like image 33
Jarek Tkaczyk Avatar answered Oct 24 '22 23:10

Jarek Tkaczyk