如何更新 Laravel Eloquent 管理的时间戳(created_at 和 updated_at)的时区?

Posted

技术标签:

【中文标题】如何更新 Laravel Eloquent 管理的时间戳(created_at 和 updated_at)的时区?【英文标题】:How to update the timezone for the timestamps (created_at and updated_at) managed by Laravel Eloquent? 【发布时间】:2013-10-05 17:59:25 【问题描述】:

我在 GMT 有一个服务器,但我想更新这些字段( *created_at* 和 *updated_at* )以在 PST 中保存时间戳

我已经做了一些测试来尝试实现这一点,但没有一个是正确的。

我将 config/application.php 更新为 'timezone' => 'America/Los_Angeles' 另外在服务器中,我将 php.ini 中的 date.timezone 更改为 'America/Los_Angeles'

但是任何这些更新都会将时区更新应用于 Laravel Eloquent 时间戳。这个字段 created_at 和 updated_at 由 Eloquent 处理。

我还使用 sudo dpkg-reconfigure tzdata 更新了 Ubuntu 服务器时区,但这个更新根本不起作用。

编辑:我需要让 Laravel Eloquent 时间戳在 PST 时区工作,以便将来插入数据库。

任何帮助都会很有用。谢谢。

【问题讨论】:

确认 - 您要更新已在 mysql 数据库中的 created_at 和 updated_at 列? 不,我想让字段 created_atupdated_at 与 PST 对齐,以便将来插入数据库。我的意思是在 php Laravel 方面。 在这种情况下,您的问题与编程无关,恐怕问题超出了社区的范围。看来 serverfault.com 是一个更好的寻求帮助的地方。 对不起,如果我没有很好地解释自己,但是问题与编程有关,与 PHP Laravel 框架有关。我需要知道是否可以修改 Eloquent 目前使用的时区,以便在保存到数据库时保存这些时间戳 created_atupdated_at 我现在看到了...支持,希望其他人会看到它。同时 - 看看这个:craigcartmell.com/article/show/2/… 【参考方案1】:

我知道这个问题有点过时了,但是我在尝试提出相同的解决方案时偶然发现了它,并想分享我是如何解决它的。

我的建议是不要更改存储消息的时区。将它们作为 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 修改器/访问器的更多信息,请查看documentation。

【讨论】:

优雅的解决方案。我喜欢您可以将 UTC 格式保留在数据库中以提高可读性的事实。另一种选择是通过覆盖 getDateFormat() 方法将时间存储在 unix 时间戳(格式“U”)中,并以观察者在检索它时提到的相同方式转换它,只是没有 strtotime() 方法。 laravel.com/docs/4.2/eloquent#timestamps 这是一个很好的答案。谢谢。【参考方案2】:

对于 Lumen,它可以在 .env 文件中使用:

DB_TIMEZONE="+03:00"

【讨论】:

【参考方案3】:

很简单,修改AppServiceProvider.php中的boot()函数

public function boot()

    //set local timezone
    date_default_timezone_set('Asia/Shanghai');

【讨论】:

糟糕的解决方案。不考虑时区偏移。您应该将日期存储为 UTC,然后通过访问器将它们转换为适当的时区是有原因的。【参考方案4】:

我不确定我是否理解您是否要更改服务器的设置以便将来输入数据库,或者您是否要更新数据库中的当前值。

如果是后者,更改服务器设置不会影响数据库中的当前记录。如果要更改现有字段的值,可以使用以下 MySQL 命令:

 update `table` set created_at = (SELECT created_at) + INTERVAL 2 HOUR;

其中table 是数据库表的名称,2 是以小时为单位的偏移量。

【讨论】:

以上是关于如何更新 Laravel Eloquent 管理的时间戳(created_at 和 updated_at)的时区?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Laravel Eloquent 更新 PostgresQL 中 jsonb 列的多个“键”

Laravel eloquent 使用关系列更新列

Laravel (Eloquent) 不更新数据库

通过 eloquent 更新 laravel 中的多行

Laravel Eloquent - 更新()函数

Laravel Eloquent 显示后更新