sql >> Databáze >  >> RDS >> Mysql

Jak aktualizovat časové pásmo pro časová razítka (created_at a updated_at) spravované Laravel Eloquent?

Vím, že tato otázka je trochu zastaralá, ale narazil jsem na ni, když jsem se snažil přijít se stejným řešením, a chtěl jsem se podělit o to, jak jsem postupoval při řešení.

Moje rada by byla neměnit časové pásmo, ve kterém jsou zprávy uloženy. Ukládat je do databáze jako UTC. Pokud budete mít úložiště nastavené na konstantní referenční rámec a poté jej převedete na jakékoli časové pásmo, ve kterém potřebujete, aby se zobrazovalo, z dlouhodobého hlediska vám ušetří spoustu bolestí hlavy.

Jako příklad jedné z těchto bolestí hlavy si představte, že se dva lidé pokoušejí koordinovat čas schůzky v různých časových pásmech, kde jeden dodržuje letní čas a druhý ne, a vy potřebujete zobrazit čas v místním čase každého uživatele. Jak těžké by bylo převést váš uložený čas PDT na řekněme America/Cayman (který nedodržuje letní čas)? A jak byste vzali v úvahu, kdy jsou časy uloženy v PST vs PDT? jak to můžeš vědět? (Tip:bez pravděpodobně stovek řádků kódu navíc, které by odpovídaly na jednu otázku, nebudete ).

Chcete-li získat časový limit ve správném časovém pásmu, jednoduše přidejte funkci mutátoru na samotný model:

use Carbon\Carbon;

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

Nyní, kdykoli uděláte $myModel->created_at bude kouzlem převedeno do správného časového pásma, ale stále budete mít UTC ve své databázi, což má rozhodně své výhody oproti jiným časovým pásmům pro trvalé úložiště.

Chcete uživatelům umožnit nastavit si vlastní časová pásma? Změňte funkci na tuto:

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

A veškerá složitost změny časových pásem, zohlednění nebo nezohlednění letního času je od vás abstrahována a můžete zapomenout, že k tomu vůbec musí dojít.

Další informace o Laravel mutátorech/accessorech najdete v dokumentaci .



  1. mysql2 gem se nedaří zkompilovat s MySQL 5.6.12 na OS X s Homebrew

  2. Cizí klíč ke složenému klíči

  3. Jak získat vícenásobné počty s jedním dotazem v MySQL

  4. Jak můžete v SQL seskupit podle rozsahů?