sql >> Base de Datos >  >> RDS >> Mysql

¿Cómo actualizar la zona horaria para las marcas de tiempo (created_at y updated_at) administradas por Laravel Eloquent?

Sé que esta pregunta está un poco anticuada, pero me topé con ella cuando intentaba encontrar la misma solución y quería compartir cómo la resolví.

Mi consejo sería no cambiar la zona horaria en la que se almacenan los mensajes. Guárdelos en la base de datos como UTC. Mantener su almacenamiento configurado en un marco de referencia constante y luego convertirlo a cualquier zona horaria en la que necesite que se muestre le ahorrará muchos dolores de cabeza a largo plazo.

Como ejemplo de uno de esos dolores de cabeza, imagine a dos personas tratando de coordinar una reunión en diferentes zonas horarias donde una observa el horario de verano y la otra no y necesita mostrar la hora en la hora local de cada usuario. ¿Qué tan difícil sería convertir su tiempo PDT almacenado para decir, América/Caimán (que no observa el horario de verano)? ¿Y cómo tomaría en cuenta cuando los tiempos se almacenan en PST vs PDT? ¿Cómo sabrías? (Sugerencia:sin probablemente cientos de líneas de código adicional solo para responder esa pregunta, no ).

Para obtener el tiempo de espera en la zona horaria correcta, simplemente agregue una función de mutación en el propio modelo:

use Carbon\Carbon;

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

Ahora, siempre que hagas $myModel->created_at se convertirá por arte de magia en la zona horaria correcta, pero aún mantiene UTC en su base de datos, lo que definitivamente tiene sus ventajas sobre otras zonas horarias para el almacenamiento persistente.

¿Quiere permitir que los usuarios establezcan sus propias zonas horarias? Cambia la función a esto:

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()
    ;
}

Y toda la complejidad de cambiar las zonas horarias, tener en cuenta el horario de verano o no, se abstrae de ti y puedes olvidar que incluso tiene que suceder.

Para obtener más información sobre los mutadores / accesores de Laravel, consulta la documentación .