Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie aktualisiere ich die Zeitzone für die von Laravel Eloquent verwalteten Zeitstempel (created_at und updated_at)?

Ich weiß, dass diese Frage etwas veraltet ist, aber ich bin darauf gestoßen, als ich versuchte, dieselbe Lösung zu finden, und wollte mitteilen, wie ich sie gelöst habe.

Mein Rat wäre, die Zeitzone, in der die Nachrichten gespeichert sind, nicht zu ändern. Speichern Sie sie in der Datenbank als UTC. Wenn Sie Ihren Speicher auf einen konstanten Referenzrahmen einstellen und ihn dann in die Zeitzone konvertieren, in der Sie ihn anzeigen möchten, ersparen Sie sich auf lange Sicht eine Menge Kopfschmerzen.

Stellen Sie sich als Beispiel für eines dieser Probleme vor, dass zwei Personen versuchen, eine Besprechungszeit in verschiedenen Zeitzonen zu koordinieren, in denen einer die Sommerzeit einhält und der andere nicht, und Sie die Zeit in der Ortszeit jedes Benutzers anzeigen müssen. Wie schwer wäre es, Ihre gespeicherte PDT-Zeit umzuwandeln, um zu sagen, Amerika/Cayman (das keine Sommerzeit einhält)? Und wie würden Sie berücksichtigen, wann Zeiten in PST vs. PDT gespeichert werden? Wie würdest du wissen? (Hinweis:Ohne wahrscheinlich Hunderte von Zeilen zusätzlichen Codes, nur um diese eine Frage zu beantworten, werden Sie nicht ).

Um die Uhrzeit in der richtigen Zeitzone anzuzeigen, fügen Sie einfach eine Mutator-Funktion zum Modell selbst hinzu:

use Carbon\Carbon;

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

Jetzt, wann immer Sie $myModel->created_at tun es wird auf magische Weise in die richtige Zeitzone konvertiert, aber Sie behalten immer noch UTC in Ihrer Datenbank, was definitiv seine Vorteile gegenüber anderen Zeitzonen für die dauerhafte Speicherung hat.

Möchten Sie Benutzern ermöglichen, ihre eigenen Zeitzonen festzulegen? Ändern Sie die Funktion wie folgt:

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

Und all die Komplexität der Änderung von Zeitzonen, Berücksichtigung der Sommerzeit oder nicht, wird Ihnen abstrahiert und Sie können vergessen, dass es überhaupt passieren muss.

Weitere Informationen zu Laravel-Mutatoren/Accessoren finden Sie in der Dokumentation .