How to format date fields before save in CakePHP 3?

10,738

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 '],
        ],

in mysql https://my.vertica.com/docs/7.1.x/HTML/Content/Authoring/SQLReferenceManual/Statements/SET/SETDATESTYLE.htm

Share:
10,738
celsowm
Author by

celsowm

Updated on June 12, 2022

Comments

  • celsowm
    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

    Alunos Controller code

    Thanks !

  • celsowm
    celsowm about 9 years
    Thanks 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
    José Lorenzo Rodríguez about 9 years
    If you are using Time objects the ORM will know exactly what format to use in the database.
  • celsowm
    celsowm about 9 years
    I've tried Time::$defaultLocale = 'pt-BR'; in AppController but the problem persists... and 'timezone' => 'BRT', in Database too
  • José Lorenzo Rodríguez
    José Lorenzo Rodríguez about 9 years
    What is the problem exactly?
  • celsowm
    celsowm about 9 years
    try to save() a date from a input text dd/mm/yyyy without convert to yyyy-mm-dd and get error
  • José Lorenzo Rodríguez
    José Lorenzo Rodríguez about 9 years
    Why are you trying to save a string in the date field instead of converting it to a Time object?
  • celsowm
    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
    José Lorenzo Rodríguez about 9 years
    @celsowm Improved my answer based on your comments.
  • celsowm
    celsowm over 7 years
    SQLServer: 'init' => ['SET DATEFORMAT DMY'],