How to format date fields before save in CakePHP 3?
Solution 1
My final solution was this on bootstrap:
date_default_timezone_set('America/Sao_Paulo');
setlocale(LC_ALL, 'pt_BR', 'pt_BR.utf-8', 'pt_BR.utf-8', 'portuguese');
Type::build('time')->useImmutable();
Type::build('date')->useImmutable()->useLocaleParser();
Type::build('datetime')->useImmutable()->useLocaleParser();
Type::build('timestamp')->useImmutable();
\Cake\I18n\Time::setToStringFormat('dd/MM/yyyy HH:mm:ss');
\Cake\I18n\Date::setToStringFormat('dd/MM/yyyy');
\Cake\I18n\FrozenTime::setToStringFormat('dd/MM/yyyy HH:mm:ss');
\Cake\I18n\FrozenDate::setToStringFormat('dd/MM/yyyy');
\Cake\I18n\I18n::locale('pt-BR'); //new !
Type::build('decimal')->useLocaleParser();
Type::build('float')->useLocaleParser();
Solution 2
maybe this could help someone.
public function beforeSave($event, $entity, $options) {
$entity->dateField = date('Y-m-d', strtotime($entity->dateField));
}
Solution 3
If you are just creating a new application with a fresh database, delete does dates having 0000-00-00 and change the column definition so it can accept nulls. Using 0000-00-00 for dates is usually a really bad thing as only errors and bugs can come out of it :)
Edit based on the comments below
It seems like the problem was getting a string field to be parsed from the local date format to what php can understand. For this task you just need to configure the DateTimeType
class to parse the dates using a locale-aware format as described here http://book.cakephp.org/3.0/en/orm/database-basics.html#parsing-localized-datetime-data
// In bootstrap.php or AppController or your controller action:
use Cake\Database\Type;
...
Type::build('datetime')->useLocaleParser();
You can also set the locale parser to parse a specific format. For the code above to work, make sure you set your application to use a locale:
I18n::locale('fr-FR')
Solution 4
Easy solution insert date format in CakePHP 3.x in Models and custom out views:
Insert ['rule' => ['date','dmy']]
Example
public function validationDefault(Validator $validator)
{
...
$validator
->add('demo_example_date', 'valid', ['rule' => ['date','dmy']]) //Format valid '30-12-2015' or '30-12-05'
->requirePresence('demo_example_date', 'create')
->notEmpty('factura_fecha');
...
return $validator;
}
Out view, set AppController
...
use Cake\I18n\Time;
use Cake\Database\Type;
Time::$defaultLocale = 'es-ES';
Time::setToStringFormat('dd-MM-YYYY');
Type::build('datetime')->useLocaleParser();
class AppController extends Controller
{
...
}
Solution 5
works for me using Postgres.
File config/app.php
in variable Datasources['default'] add command 'SET datestyle TO ISO, DMY' to init
'Datasources' => [
'default' => [
'init' => ['SET datestyle TO ISO, DMY '],
],
celsowm
Updated on June 12, 2022Comments
-
celsowm almost 2 years
I used this in AppController:
Time::setToStringFormat('dd/MM/YYYY');
The date field in my form is a input type "text" to allow my user writes something like 31/12/2015.
However when I try to save (MySQL date) I get some errors of Time Class because inside the table the value now is 00-00-0000
Thanks !
-
celsowm about 9 yearsThanks Lorenzo but in MySQL the date format is YYYY-MM-DD and how can I be able to insert date using this format without functions like STR_TO_DATE( "31/05/2014", "%m/%d/%Y" ) or ? In Cake 1.2 I used a Behavior called DateFormatter.
-
José Lorenzo Rodríguez about 9 yearsIf you are using Time objects the ORM will know exactly what format to use in the database.
-
celsowm about 9 yearsI've tried Time::$defaultLocale = 'pt-BR'; in AppController but the problem persists... and 'timezone' => 'BRT', in Database too
-
José Lorenzo Rodríguez about 9 yearsWhat is the problem exactly?
-
celsowm about 9 yearstry to save() a date from a input text dd/mm/yyyy without convert to yyyy-mm-dd and get error
-
José Lorenzo Rodríguez about 9 yearsWhy are you trying to save a string in the date field instead of converting it to a Time object?
-
celsowm about 9 years@lorenzo input text for date is a pattern in my job place ! They don't like 3 "selects" fields for a date field
-
José Lorenzo Rodríguez about 9 years@celsowm Improved my answer based on your comments.
-
celsowm over 7 yearsSQLServer: 'init' => ['SET DATEFORMAT DMY'],