Mysql
 sql >> Database >  >> RDS >> Mysql

Come aggiornare il fuso orario per i timestamp (created_at e update_at) gestiti da Laravel Eloquent?

So che questa domanda è un po' datata, ma mi sono imbattuto in essa quando ho cercato di trovare la stessa soluzione e volevo condividere come ho risolto.

Il mio consiglio sarebbe di non modificare il fuso orario in cui sono archiviati i messaggi. Archiviarli nel database come UTC. Mantenere lo spazio di archiviazione impostato su un quadro di riferimento costante e quindi convertirlo nel fuso orario in cui è necessario visualizzarlo ti farà risparmiare un sacco di mal di testa a lungo termine.

Come esempio di uno di questi mal di testa, immagina due persone che cercano di coordinare l'ora di una riunione in fusi orari diversi in cui una osserva l'ora legale e l'altra no e devi visualizzare l'ora nell'ora locale di ciascun utente. Quanto sarebbe difficile convertire l'ora PDT memorizzata per dire, l'America/Cayman (che non osserva l'ora legale)? E come prenderesti in considerazione quando i tempi sono archiviati in PST rispetto a PDT? Come lo sapresti? (Suggerimento:senza probabilmente centinaia di righe di codice extra solo per rispondere a questa domanda, non ).

Per ottenere il timeout nel fuso orario corretto, aggiungi semplicemente una funzione mutatore sul modello stesso:

use Carbon\Carbon;

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

Ora, ogni volta che esegui $myModel->created_at verrà magicamente convertito nel fuso orario corretto, ma manterrai comunque UTC nel tuo database che ha sicuramente i suoi vantaggi rispetto ad altri fusi orari per l'archiviazione persistente.

Vuoi consentire agli utenti di impostare i propri fusi orari? Cambia la funzione in questo:

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 tutta la complessità della modifica dei fusi orari, tenendo conto o meno dell'ora legale, ti viene sottratta e puoi persino dimenticare che deve accadere.

Per ulteriori informazioni sui mutatori/accessori Laravel, consulta la documentazione .