Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como atualizar o fuso horário dos timestamps (created_at e updated_at) gerenciados pelo Laravel Eloquent?


Eu sei que essa pergunta é um pouco datada, mas me deparei com ela ao tentar encontrar a mesma solução e queria compartilhar como fiz para resolvê-la.

Meu conselho seria não alterar o fuso horário em que as mensagens são armazenadas. Armazene-as no banco de dados como UTC. Manter seu armazenamento definido para um quadro de referência constante e, em seguida, convertê-lo para qualquer fuso horário em que você precise que ele seja exibido, economizará muita dor de cabeça a longo prazo.

Como exemplo de uma dessas dores de cabeça, imagine duas pessoas tentando coordenar um horário de reunião em fusos horários diferentes, onde um observa o horário de verão e o outro não e você precisa exibir o horário no horário local de cada usuário. Quão difícil seria converter seu tempo PDT armazenado para dizer, o America/Cayman (que não observa o horário de verão)? E como você levaria em conta quando os tempos são armazenados em PST vs PDT? Como você saberia? (Dica:sem provavelmente centenas de linhas de código extra apenas para responder a essa pergunta, você não vai ).

Para obter o tempo limite no fuso horário correto, basta adicionar uma função de mutação no próprio modelo:
use Carbon\Carbon;

class MyModel extends Eloquent
{
    public function getCreatedAtAttribute($value)
    {
        return Carbon::createFromTimestamp(strtotime($value))
            ->timezone('America/Los_Angeles')
            ->toDateTimeString()
        ;
    }
}

Agora, sempre que você fizer $myModel->created_at ele será magicamente convertido no fuso horário correto, mas você ainda mantém o UTC em seu banco de dados, o que definitivamente tem suas vantagens sobre outros fusos horários para armazenamento persistente.

Deseja permitir que os usuários definam seus próprios fusos horários? Altere a função para isso:
public function getCreatedAtAttribute($value)
{
    $user = Auth::user();
    // If no user is logged in, we'll just default to the 
    // application's timezone
    $timezone = $user ? $user->timezone : Config::get('app.timezone');

    return Carbon::createFromTimestamp(strtotime($value))
        ->timezone($timezone)
        // Leave this part off if you want to keep the property as 
        // a Carbon object rather than always just returning a string
        ->toDateTimeString()
    ;
}

E toda a complexidade de mudar os fusos horários, levando em consideração ou não o horário de verão, é abstraída de você e você pode esquecer que isso tem que acontecer.

Para obter mais informações sobre os mutadores / acessadores do Laravel, confira a documentação .