Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak zaktualizować strefę czasową dla znaczników czasu (created_at i updated_at) zarządzanych przez Laravel Eloquent?

Wiem, że to pytanie jest nieco przestarzałe, ale natknąłem się na nie, próbując wymyślić to samo rozwiązanie, i chciałem podzielić się tym, jak go rozwiązałem.

Radzę nie zmieniać strefy czasowej, w której przechowywane są wiadomości. Przechowuj je w bazie danych jako UTC. Utrzymywanie pamięci masowej ustawionej na stałe ramy odniesienia, a następnie konwertowanie jej na dowolną strefę czasową, w której jest wyświetlana, zaoszczędzi ci mnóstwo bólu głowy na dłuższą metę.

Jako przykład jednego z tych bólów głowy wyobraź sobie dwie osoby próbujące koordynować czas spotkania w różnych strefach czasowych, w których jedna obserwuje czas letni, a druga nie, i musisz wyświetlić czas w czasie lokalnym każdego użytkownika. Jak trudno byłoby przekonwertować zapisany czas PDT na, powiedzmy, Amerykę/Kajmany (który nie przestrzega czasu letniego)? A jak byś wziął pod uwagę, że czasy są przechowywane w PST vs PDT? Skąd miałbyś wiedzieć? (Wskazówka:bez prawdopodobnie setek dodatkowych linijek kodu tylko po to, by odpowiedzieć na to jedno pytanie, nie ).

Aby uzyskać limit czasu we właściwej strefie czasowej, po prostu dodaj funkcję mutatora do samego modelu:

use Carbon\Carbon;

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

Teraz, kiedy tylko zrobisz $myModel->created_at zostanie on w magiczny sposób przekonwertowany na prawidłową strefę czasową, ale nadal będziesz przechowywać UTC w swojej bazie danych, co z pewnością ma swoje zalety w porównaniu z innymi strefami czasowymi do trwałego przechowywania.

Chcesz zezwolić użytkownikom na ustawianie własnych stref czasowych? Zmień funkcję na następującą:

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 cała złożoność zmiany stref czasowych, branie pod uwagę czasu letniego lub nie, jest oddalana od Ciebie i możesz zapomnieć, że to nawet musi się wydarzyć.

Aby uzyskać więcej informacji na temat mutatorów/akcesorów Laravela, zapoznaj się z dokumentacją .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL LIKE z zasięgiem nie działa

  2. Jak mogę WYBRAĆ wiersze z MAX (wartość kolumny), PARTITION według innej kolumny w MYSQL?

  3. Pokaż wszystkie daty między, nawet jeśli nie ma wyników

  4. Jak uzyskać listę dat między dwiema datami w zapytaniu wybierającym mysql

  5. Jak przetestować połączenie z bazą danych MySQL za pomocą skryptu?