Laravel formate date

Posted on: April 08, 2025 07:51 PM

Posted by: Renato

Categories: Laravel

Views: 204

Estou enviando uma data para meu controller e meu controller envia para um helper para formatar a data. Esta formatando uma data incorreta. Exemplo: "01/01/3024 23:59" Incorreto: "2024-01-19 07:40:00" - Codigo controller:

        $curso->data_fim = Helpers::formataDatetimeParaBanco($request->data_fim);
        - Function do helper
        /**
        * Recebe datetime em formato br e passa para formato database
        * @param String '01/11/2016 14:31' '01/11/2016 14:31:00'
        * @return String '2016-11-01 14:31:00'
        */
        public static function formataDatetimeParaBanco($date) {
        if (($date == null) || ($date == ""))
        return null;
        $len = strlen($date);
        $date = substr($date, 6, 4) . '-' . substr($date, 3, 2) . '-' . substr($date, 0, 2) . ' ' . substr($date, 11);
        if ($len == 16)
        $date .= ':00';
        return $date;
    }
    
- Como acerto esta data para "3024-01-01 23:59:00" ?

O problema está na função formataDatetimeParaBanco que está fazendo um parsing manual da data sem considerar anos com mais de 4 dígitos. Quando você envia "01/01/3024 23:59", a função está pegando os caracteres das posições erradas para o ano.

Vamos corrigir a função para lidar com anos longos:

php
public static function formataDatetimeParaBanco($date) {
     if (($date == null) || ($date == ""))
         return null;
     
     // Divide a string em data e hora
     $parts = explode(' ', $date);
     $datePart = $parts[0];
     $timePart = $parts[1] ?? '00:00';
     
     // Divide a data em dia, mês e ano
     $dateComponents = explode('/', $datePart);
     $day = $dateComponents[0];
     $month = $dateComponents[1];
     $year = $dateComponents[2];
     
     // Formata a hora (adiciona segundos se necessário)
     if (strlen($timePart) == 5) {
         $timePart .= ':00';
     }
     
     return "$year-$month-$day $timePart";
 }

Esta nova versão:

  1. Primeiro divide a string em partes de data e hora

  2. Separa os componentes da data (dia, mês, ano) corretamente

  3. Lida com anos de qualquer tamanho (4 dígitos ou mais)

  4. Formata a parte do tempo adequadamente

Para o input "01/01/3024 23:59", agora retornará corretamente "3024-01-01 23:59:00".

Uma alternativa ainda mais robusta seria usar a classe DateTime:

php
public static function formataDatetimeParaBanco($date) {
     if (empty($date)) {
         return null;
     }
     
     $datetime = DateTime::createFromFormat('d/m/Y H:i', $date);
     if ($datetime === false) {
         $datetime = DateTime::createFromFormat('d/m/Y H:i:s', $date);
     }
     
     return $datetime ? $datetime->format('Y-m-d H:i:s') : null;
 }

Esta versão com DateTime é mais limpa e menos propensa a erros, mas pode ter problemas com anos muito distantes (dependendo da versão do PHP). Para anos como 3024, deve funcionar sem problemas.

Aqui está a função com as anotações de propriedade (PHPDoc) adequadas, incluindo tipo de parâmetro, tipo de retorno e descrição detalhada:

php
/**
     * Converte uma data no formato brasileiro (DD/MM/YYYY HH:MM) para o formato do banco de dados (YYYY-MM-DD HH:MM:SS)
     * 
     * @param string|null $date Data no formato brasileiro (DD/MM/YYYY HH:MM ou DD/MM/YYYY HH:MM:SS)
     *                          ou string vazia. Ex: "01/01/3024 23:59" ou "01/01/2024 23:59:30"
     * 
     * @return string|null Retorna a data no formato do banco (YYYY-MM-DD HH:MM:SS) ou null se:
     *                    - $date for null
     *                    - $date for string vazia
     *                    - $date estiver em formato inválido
     * 
     * @example formataDatetimeParaBanco("01/01/3024 23:59") retorna "3024-01-01 23:59:00"
     * @example formataDatetimeParaBanco("15/12/2023 08:30:45") retorna "2023-12-15 08:30:45"
     * @example formataDatetimeParaBanco("") retorna null
     */
    public static function formataDatetimeParaBanco(?string $date): ?string
    {
        if (empty($date)) {
            return null;
        }
        
        $datetime = DateTime::createFromFormat('d/m/Y H:i', $date);
        if ($datetime === false) {
            $datetime = DateTime::createFromFormat('d/m/Y H:i:s', $date);
        }
        
        return $datetime ? $datetime->format('Y-m-d H:i:s') : null;
    }

Principais melhorias nas anotações:

  1. Adicionado @param string|null indicando que o parâmetro pode ser string ou null

  2. Adicionado : ?string na declaração da função (type hint de retorno)

  3. Documentação mais clara dos comportamentos de entrada/saída

  4. Adicionados exemplos práticos com @example

  5. Documentação dos casos que retornam null

  6. Menção explícita aos formatos suportados de entrada

Isso fornece uma documentação completa para:

  • Desenvolvedores que precisam usar a função

  • Ferramentas de IDE (como PHPStorm, VSCode)

  • Ferramentas de documentação automática

  • Análise estática de código

Ao tentar salvar a data deu este erro 0 rows updated when should have been 1 redudi o ano data e salvou com 0000-00-00 00:00:00 Valide a data ( 'data_fim' => 'required') para nao ser maior que 5 anos ou data incorreta.

       $validator = Validator::make($request->all(), [
       'id_curso' => 'required|numeric',
       'nome' => 'required|min:3|max:' . $tamanho_nome,
       'nome_reduzido' => 'required|max:' . $tamanho_nome,
       'coordenadores' => 'required',
       'status' => 'required|in:A,I,D,P,T,J',
       'ordem' => 'required|numeric',
       'acesso_pergunte_professor' => 'required|in:S,N',
       'destaque_home' => 'required|in:S,N',
       'carga_horaria' => 'required|numeric',
       'tempo_acesso' => 'required|numeric',
       'data_inicio' => 'required',
       'data_fim' => 'required',
       'data_inicio_venda' => 'required',
       'data_fim_venda' => 'required',
       'acesso_individual' => 'numeric',
       'cor' => 'string|required',
       'categoria_curso' => 'required|in:oab_2fase,oab_1fase,interno,concursos,pratica,enem,pos_graduacao',
       'tipo_curso' => 'required_unless:categoria_curso,interno|in:isolado,gratuito,plano,combo,cronograma,treinamento,repescagem,regular,assinatura,presencial,tcc,mentoria,extensivo,intensivo,imersao',
       ]);
    

Solução para Validação de Data

Parece que você está enfrentando dois problemas:

  1. A data está sendo salva como 0000-00-00 00:00:00 quando inválida

  2. Precisa validar se a data não é maior que 5 anos no futuro e se é uma data válida

Solução para o Validator

Vamos modificar seu validator para incluir as validações de data corretamente:

php
$validator = Validator::make($request->all(), [
                 'id_curso' => 'required|numeric',
                 'nome' => 'required|min:3|max:' . $tamanho_nome,
                 // ... outros campos ...
                 'data_fim' => [
                     'required',
                     'date_format:d/m/Y H:i',
                     function ($attribute, $value, $fail) {
                         // Converte para objeto DateTime
                         $data = DateTime::createFromFormat('d/m/Y H:i', $value);
                         
                         if (!$data) {
                             $fail('O formato da data final é inválido.');
                             return;
                         }
                         
                         // Verifica se a data não é mais que 5 anos no futuro
                         $dataAtual = new DateTime();
                         $diferenca = $dataAtual->diff($data);
                         
                         if ($diferenca->y > 5) {
                             $fail('A data final não pode ser mais que 5 anos no futuro.');
                         }
                         
                         // Verifica se a data é válida (não caiu no "0000-00-00")
                         if ($data->format('Y') < 1000) {
                             $fail('A data final informada é inválida.');
                         }
                     }
                 ],
                 // ... outros campos de data com validação similar ...
                 'data_inicio' => [
                     'required',
                     'date_format:d/m/Y H:i',
                     function ($attribute, $value, $fail) {
                         $data = DateTime::createFromFormat('d/m/Y H:i', $value);
                         
                         if (!$data) {
                             $fail('O formato da data de início é inválido.');
                         }
                     }
                 ],
                 // ... outros campos ...
             ]);

Solução para o Problema do "0000-00-00"

O problema ocorre porque a data está sendo passada para o banco em um formato inválido. Modifique seu helper para incluir validação:

php
/**
              * Converte uma data no formato brasileiro para o formato do banco de dados
              * com validação rigorosa
              */
             public static function formataDatetimeParaBanco(?string $date): ?string
             {
                 if (empty($date)) {
                     return null;
                 }
                 
                 // Tenta ambos os formatos (com e sem segundos)
                 $datetime = DateTime::createFromFormat('d/m/Y H:i:s', $date);
                 if ($datetime === false) {
                     $datetime = DateTime::createFromFormat('d/m/Y H:i', $date);
                 }
                 
                 // Se ainda falhar, retorna null para evitar data inválida
                 if ($datetime === false) {
                     return null;
                 }
                 
                 // Verifica se o ano é válido (maior que 1000)
                 if ($datetime->format('Y') < 1000) {
                     return null;
                 }
                 
                 return $datetime->format('Y-m-d H:i:s');
             }

Validação Adicional no Controller

No seu controller, antes de salvar, você pode fazer uma validação adicional:

php
// Converter e validar a data
             $dataFim = Helpers::formataDatetimeParaBanco($request->data_fim);
             
             if (!$dataFim) {
                 return back()->withErrors(['data_fim' => 'Data final inválida ou formato incorreto'])->withInput();
             }
             
             // Verificar se a data não é mais que 5 anos no futuro
             $dataAtual = new DateTime();
             $dataFimObj = new DateTime($dataFim);
             $diferenca = $dataAtual->diff($dataFimObj);
             
             if ($diferenca->y > 5) {
                 return back()->withErrors(['data_fim' => 'A data final não pode ser mais que 5 anos no futuro'])->withInput();
             }
             
             // Agora pode salvar com segurança
             $curso->data_fim = $dataFim;

Observações Importantes

  1. Todas as validações devem ser feitas tanto no frontend quanto no backend

  2. O MySQL/MariaDB rejeita datas inválidas (como '0000-00-00') em versões recentes

  3. Considere usar campos date ou datetime no banco de dados em vez de strings

  4. Para Laravel 8+, você pode usar as regras de validação embutidas como after, before etc.

- Renato Lucena

3

Share

Donate to Site


About Author

Renato

Developer

Add a Comment
Comments 0 Comments

No comments yet! Be the first to comment

Blog Search


Categories

Laravel (227) PHP (151) linux (124) Variados (110) ubuntu (58) Dicas (58) developer (48) postgresql (45) database (44) sql (42) Docker (32) mysql (31) front-end (31) devops (26) webdev (24) programming (23) eloquent (19) aws (19) tecnologia (19) dba (18) OUTROS (17) backend (16) laravelphp (16) dev (12) debian (12) react (10) reactjs (10) 100DaysOfCode (10) git (10) javascript (9) nginx (9) inteligencia-artificial (9) PHP Swoole (9) node (9) linux-tools (8) Architecture (8) ciencia (7) github (7) vue (7) arquitetura (6) windows (6) api (6) vscode (6) nodejs (6) webservice (6) vim (6) jwt (6) apache (5) macox (5) s3 (5) servers (5) ia (5) authentication (5) reactnative (5) rest (5) DevSecOps (5) openai (4) google (4) npm (4) opensource (4) mariadb (4) jenkins (4) Kubernetes (4) gitlab (4) angular (4) autenticacao (4) shell (4) mongodb (4) angularjs (4) inteligenciadedados (4) Padrao de design (4) artigo (4) wsl (4) Swoole (4) lets-encrypt (4) query (4) Raspberry (4) db (3) politica (3) intel (3) CMS (2) sail (3) script (3) performance (3) js (3) mysqli (3) Black Hat (3) RabbitMQ (3) educacao (3) mac (3) fedora (3) containers (3) json (3) authorization (3) phpswoole (3) ddd (3) blade (3) terminal (3) log (3) macos (3) web (2) jobs (3) websocket (3) ssh (3) bash (3) hardware (3) tests (3) imagick (2) maps (2) colors (2) Passport (2) JQuery (2) phpfpm (2) autorizacao (2) monitoring (2) laptop (2) gnome (2) powerbi (2) telefonia (2) nvm (2) android (2) unix (2) magento (2) iot (2) ffmpeg (2) combustivel (2) webhook (2) microservices (2) Curisidades (2) Solid (2) zsh (2) Go (2) BigLinux (2) POO (2) LazyVim (2) gource (2) Python (2) Oauth2 (2) openswoole (2) artificialintelligence (2) security (2) bancodedados (2) tailwind (2) homeOffice (2) html (2) ElonMusk (2) redis (2) claude (2) ArchLinux (2) java (2) saude (1) seguranca (2) auth (2) cron (2) phpunit (2) kube (2) multiple_authen (2) policia (2) neovim (2) golang (2) noticias (2) livros (2) Transcribe (2) lumen (1) Hyperf (1) replication (1) faceapp (1) vala (1) cloudstack (1) rpi (1) apple (1) oracle (1) iode (1) ffaa (1) vpn (1) MeioAmbiente (1) firefox (1) composer (1) scheduling (1) Asahi (1) pendrive (1) microservice (1) front (1) cor (1) auth (1) modelagemdedados (1) k8s (1) gasolina (1) wsl2 (1) csv (1) soap (1) piada (1) KubeCon (1) zorin-os (1) spring-boot (1) backup (1) playwright (1) Deepin (1) storage (1) benchmark (1) networking (1) Swoole (1) biologia (1) node-red (1) LETSENCRYPT (1) Grunt (1) Diagramas (1) boot (1) haru (1) dracula (1) TrabalhoEmEquipe (1) Brasil (1) queue (1) agi (1) llama (1) hotfix (1) economia (1) transcription (1) cache (1) Amazon (1) October (1) odd (1) m1 (1) Error (1) cinnamon (1) repmgr (1) federal (1) ruby (1) AppSec (1) orm (1) ArquiteturaDeSoftware (1) Passwordless (1) memcached (1) flow (1) compression (1) athena (1) front (1) wine (1) covid19 (0) services (1) phpjasper (1) models (1) kali-linux (1) geojson (1) yarn (1) picpay (1) Monolith (1) banco (1) PNPM (1) Desenvolvedor (1) Structurizr (1) symfony (1) presenter (1) lider (1) guard (1) tensorflow (1) bootstrap (1) nuance (1) historia (1) dropbox (1) traefik (1) bug (1) akitando (1) llm (1) htm (1) transformers (1) cavalotroia (1) translate (1) certbot (1) Oh My Zsh (1) ibm (1) escopos (1) usb (1) ckeditor (1) API_KEY_GOOGLE_MAPS (1) Manjaro (1) vicuna (1) coding (1) rust (1) markdown (1) JasperReports (1) Fibonacci (1) community (1) Samurai (1) payment (1) messaging (1) Jesus (1) flutter (1) Migration (1) workflow (1) cqrs (1) kitematic (1) geospacial (1) yeshua (1) data (1) sonarqube (1) Axios (1) pipelines (1) Mozilla (1) kvm (1) GitOps (1) sqlite (1) podcast (1) n8n (1) LaravelFilament (1) God (1) DesenvolvimentoProfissional (1) sw (1) bigtech (1) postgres (1) NoCookies (1) LeetCode (1) governancadedados (1) prf (1) nosql (1) Lideranca (1) Hackers (1) Bots (1) pytorch (1) nuxt (1) liquid (1) ec2 (1) transaction (1) c4 (1) rancher (1) algoritimo (1) Observability (1) Elasticsearch (1) http (1) TypeScript (1) chatgpt (1) idiomas (1) eventdrive (1) uuid (1) restfull (1) aplicativo (1) optimization (1) mapas (1) Fetch (1) collections (1) RustLang (1) matematica (1) Filament (1) compactar (1) paypal (1) microg (1) forcas armadas (1) militar (1) fullsta (1) smartphones (1) automacao (1) Monitor (1) zend (1) spaceship (1) PKCE (1) l2tp (1) Glacier (1) laraveloctane (1) Deus (1) binaural (1) gpt (1) bolsonaro (1) privacidade (1) linkedin (1) documentation (1) brain (1) adb (1) nvidia (1) host (1) ecommerce (1) c4-models (1) altadisponibilidade (1) octane (1) lucena (1) OOD (0) controllers (0)

New Articles



Get Latest Updates by Email