Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment mettre à jour le fuseau horaire pour les horodatages (created_at et updated_at) gérés par Laravel Eloquent ?

Je sais que cette question date un peu, mais je suis tombé dessus en essayant de trouver la même solution et je voulais partager comment j'ai procédé pour la résoudre.

Mon conseil serait de ne pas modifier le fuseau horaire dans lequel les messages sont stockés. Stockez-les dans la base de données au format UTC. Garder votre stockage défini sur un cadre de référence constant, puis le convertir dans le fuseau horaire dans lequel vous en avez besoin vous évitera des maux de tête à long terme.

À titre d'exemple de l'un de ces maux de tête, imaginez deux personnes essayant de coordonner une heure de réunion dans différents fuseaux horaires où l'un observe l'heure d'été et l'autre non et vous devez afficher l'heure dans l'heure locale de chaque utilisateur. À quel point serait-il difficile de convertir votre heure PDT stockée pour dire, l'Amérique/Cayman (qui n'observe pas l'heure d'été) ? Et comment prendriez-vous en compte le moment où les heures sont stockées dans PST vs PDT ? Comment saurais tu? (Astuce :sans probablement des centaines de lignes de code supplémentaires juste pour répondre à cette question, vous ne le ferez pas ).

Pour obtenir l'heure d'expiration dans le bon fuseau horaire, ajoutez simplement une fonction de mutation sur le modèle lui-même :

use Carbon\Carbon;

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

Maintenant, chaque fois que vous faites $myModel->created_at il sera magiquement converti dans le bon fuseau horaire, mais vous conserverez toujours l'UTC dans votre base de données, ce qui a certainement ses avantages par rapport aux autres fuseaux horaires pour un stockage persistant.

Vous voulez laisser les utilisateurs définir leurs propres fuseaux horaires ? Remplacez la fonction par ceci :

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

Et toute la complexité du changement de fuseau horaire, en tenant compte ou non de l'heure d'été, vous est retirée et vous pouvez oublier que cela doit même arriver.

Pour plus d'informations sur les mutateurs / accesseurs Laravel, consultez la documentation .