[PROMOÇÃO] Assine com + 30% de desconto ANUAL MENSAL (últimas horas)
Allex Carvalho
Criador Allex Carvalho 07/01/2023

Bom dia,

Atualizei o Laravel 8 para o 9 e depois desta atualização, percebi um erro ao inserir registro numa tabela que contém uma coluna datetime. Segue a mensagem de erro:

SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '2023-01-22 23:59:59 08:44:05' for column 'due_date' at row 1 (SQL: insert into `companies_release` (`user_id`, `due_date`, `type`, `company_id`, `updated_at`, `created_at`) values (1, 2023-01-22 23:59:59 08:44:05, Automático, 1, 2023-01-07 08:44:05, 2023-01-07 08:44:05))

CompanyService.php
// Inseri a Empresa
$company = $this->repository->createCompany($data);

// Inseri os telefones da Empresa
$this->savePhones($company, $typePhones, $phones, $isWhatsapp);

// Libera 15 dias iniciais para a Empresa
$this->repository->insertRelease($company, now()->addDays(15)->endOfDay());

Acima, a inserção para no insertRelease. Deveria adicionar 15 dias para teste da aplicação. Se enviar somente a data, inseri o registro. Se enviar a data e o horário, a aplicação está concatenando o horário atual junto ao horário que estou enviando.

CompanyRepository.php

public function insertRelease(Company $company, $dueDate, $additional = 0, $type = 'Automático') {
    return $company->releases()->create([
        'user_id' => auth()->user()->id,
        'due_date' => $dueDate,
        'additional' => $additional,
        'type' => $type
    ]);
}

 

Pode ajudar com esse problema?

Obrigado pela atenção.

 

Manager Carlos Ferreira 07/01/2023

Olá, Allex!
Tudo bem?

Qual o formato dessa coluna "due_date" no banco de dados?

Você pode fazer o casting deste valor, diretamente no model: https://laravel.com/docs/9.x/eloquent-mutators#date-casting

Carlos Ferreira
Criador Allex Carvalho 07/01/2023

A coluna é datetime:

$table->id();
$table->unsignedBigInteger('company_id');
$table->unsignedBigInteger('user_id');
$table->dateTime('due_date');
$table->string('type', 12)->comment('Automático, Manual');
$table->timestamps();

 

 

Cheguei a testar com o casting, mas continuou com o mesmo erro:

CompanyRelease.php

<?php

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class CompanyRelease extends Model
{
    use HasFactory;

    protected $table = 'companies_release';
    protected $fillable = [
        'company_id', 'user_id', 'due_date', 'type'
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array
     */
    protected $casts = [
        'due_date' => 'datetime:Y-m-d H:i:s',
    ];

    public function company() {
        return $this->belongsTo(Company::class);
    }

    public function user() {
        return $this->belongsTo(User::class);
    }
}

 

SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '2023-01-22 23:59:59 09:13:36' for column 'due_date' at row 1 (SQL: insert into `companies_release` (`user_id`, `due_date`, `type`, `company_id`, `updated_at`, `created_at`) values (1, 2023-01-22 23:59:59 09:13:36, Automático, 2, 2023-01-07 09:13:36, 2023-01-07 09:13:36))
Incorrect datetime value: '2023-01-22 23:59:59 09:13:36' for column 'due_date' at row 1
Allex Carvalho
Manager Carlos Ferreira 07/01/2023

Olá, Allex!

Está estranho, ignorou legal o seu cast de data.

Experimenta criar um mutator:
https://laravel.com/docs/9.x/eloquent-mutators#defining-a-mutator

E usa a classe de Carbon para converter a data:
// use Carbon\Carbon;
Carbon::make($date)->format('Y-m-d H:i:s');

Após isso, me diga se deu certo.

Carlos Ferreira
Criador Allex Carvalho 07/01/2023

Boa tarde,

Agora mudou o erro:

Could not parse '2023-01-24 23:59:59 17:46:42': Failed to parse time string (2023-01-24 23:59:59 17:46:42) at position 20 (1): Double time specification

 

Allex Carvalho
Manager Carlos Ferreira 07/01/2023

Não ficou claro o erro, foi a classe de Carbon que gerou a exception?

Carlos Ferreira
Criador Allex Carvalho 07/01/2023

Quando manda inserir, está retornando o erro acima. Aparentemente é com a conversão da data. Como está passando dois times, deu o erro.

Allex Carvalho
Manager Carlos Ferreira 07/01/2023

Sim sim, só queria saber de onde veio o erro, e foi da classe de Carbon, ou do Core do Laravel.

--

Sua data tem dois times, por isso o erro na classe de Carbon, e por isso o Eloquent não consegue fazer o casting.

--

Experimenta assim:
Carbon::make($date)->format('Y-m-d');

Acho que vai dar o mesmo erro.

--

Experimenta cortar a string (gambiarra temporária):
$date = '2023-01-24 23:59:59 17:46:42';
$date = substr($date, 0, 19);
Carbon::make($date)->format('Y-m-d H:i:s');

Carlos Ferreira
Criador Allex Carvalho 07/01/2023

Então, se no service passar da forma abaixo, passa sem erros. Mesmo sem o casting ou o mutator.

 

$this->repository->insertRelease($company, now()->addDays(15)->endOfDay()->format('Y-m-d'));

 

Allex Carvalho
Criador Allex Carvalho 07/01/2023

A questão é que quando informo o horário, está dando erro. É como se a aplicação concatenasse o horário atual ao final da data e hora que informei.

Allex Carvalho
Manager Carlos Ferreira 07/01/2023

Deixa assim:
$startDay = now()->addDays(15);
$startDay->copy()->endOfDay();

Carlos Ferreira
Criador Allex Carvalho 07/01/2023

O local correto para a alteração seria no service ou no model pelo mutator?

Allex Carvalho
Manager Carlos Ferreira 07/01/2023

Pode ser onde você criou essa data:
$this->repository->insertRelease($company, now()->addDays(15)->endOfDay()->format('Y-m-d'));

Se quiser antes de mudar o código, apenas criar uma rota para testar este formato da data, só para ver se realmente funcionou, isso vai agilizar o seu lado:
Route::get('/test-date', function () {
    $startDay = now()->addDays(15);
    $finalDate = $startDay->copy()->endOfDay();
    dd($finalDate);
});

Carlos Ferreira
Criador Allex Carvalho 07/01/2023

Fiz a alteração, ficou desta forma:

// Libera 15 dias iniciais para a Arena
$dueDate = now()->addDays(15);
$dueDate->copy()->endOfDay();

$this->repository->insertRelease($company, $dueDate);


E continua com o mesmo erro. A diferença é que não pegou a data final do dia. Duplicou o mesmo horário.

SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '2023-01-25 18:39:08 18:39:08' for column 'due_date' at row 1 (SQL: insert into `companies_release` (`user_id`, `due_date`, `type`, `company_id`, `updated_at`, `created_at`) values (1, 2023-01-25 18:39:08 18:39:08, Automático, 7, 2023-01-10 18:39:08, 2023-01-10 18:39:08))
Allex Carvalho
Manager Carlos Ferreira 07/01/2023

Como está o timezone da sua aplicação?

--

Isso é para funcionar:
// use Carbon\Carbon;
Carbon::now()->addDays(15)->format('Y-m-d H:i:s');

Carlos Ferreira
Criador Allex Carvalho 07/01/2023

Mesmo erro anterior, repetiu o horário duas vezes. O time zone está assim:

'timezone' => 'America/Sao_Paulo',

 

Allex Carvalho
Manager Carlos Ferreira 07/01/2023

Rodei um teste aqui para ter certeza, e veja, funciona certinho o código que passei: https://prnt.sc/jP_1aG5XAJsP

Talvez, está gerando em outro local a data, se quiser compartilhar o código comigo.

Carlos Ferreira
Criador Allex Carvalho 07/01/2023

A data e hora no service é gerada como preciso, 2023-01-25 23:59:59. O problema é que ao usar o eloquent para gravar no banco, está concatenando o horário atual ao final do dado, exemplo: 2023-01-25 23:59:59 08:35:15.

Como posso compartilhar o código contigo?

Obrigado pela atenção.

Allex Carvalho
Manager Carlos Ferreira 07/01/2023

Compartilha pelo GitHub, se possível! :-)

Carlos Ferreira
Criador Allex Carvalho 07/01/2023

Qual conta no Google para compartilhar?

Allex Carvalho
Criador Allex Carvalho 07/01/2023

Conta do GitHub.

Allex Carvalho
Sabe a Solução? Ajude a resolver!

Precisa estar logado para conseguir responder a este ticket!

Clique Aqui Para Entrar!