我知道这个问题有点过时了,但是我在尝试提出相同的解决方案时偶然发现了它,并想分享我是如何解决它的。
我的建议是不要更改存储消息的时区。将它们作为 UTC 存储在数据库中。将您的存储设置为恒定的参考框架,然后将其转换为您需要显示的任何时区,从长远来看,这将为您省去很多麻烦。
作为其中一个令人头疼的例子,想象两个人试图在不同的时区协调会议时间,一个人遵守 DST 而一个人没有,您需要以每个用户的本地时间显示时间。将存储的 PDT 时间转换为 America/Cayman(不遵守 DST)有多难?当时间存储在 PST 和 PDT 中时,您将如何考虑?你怎么知道的?(提示:可能没有数百行额外的代码来回答一个问题,你不会)。
要在正确的时区中超时,只需在模型本身上添加一个 mutator 函数:
use Carbon\Carbon;
class MyModel extends Eloquent
{
public function getCreatedAtAttribute($value)
{
return Carbon::createFromTimestamp(strtotime($value))
->timezone('America/Los_Angeles')
->toDateTimeString()
;
}
}
现在,无论何时,$myModel->created_at
它都会神奇地转换为正确的时区,但您仍将 UTC 保留在您的数据库中,这绝对比其他时区具有持久存储的优势。
想让用户设置自己的时区吗?把函数改成这样:
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()
;
}
更改时区的所有复杂性,是否考虑夏令时都已从您身上抽象出来,您甚至可以忘记它甚至必须发生。
有关 Laravel 修改器/访问器的更多信息,请查看文档。