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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19084619/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 08:29:57  来源:igfitidea点击:

How to update the timezone for the timestamps (created_at and updated_at) managed by Laravel Eloquent?

phpmysqltimezonelaraveleloquent

提问by larc000

I have a server in GMT but I want to update those fields ( *created_at* and *updated_at* ) to save timestamps in PST.

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

I've already did some tests trying to accomplish this but none of them were correct.

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

  • I update the config/application.phpto 'timezone' => 'America/Los_Angeles'
  • Also in the server I've change the date.timezonein php.inito 'America/Los_Angeles'
  • 我将config/application.php更新为'timezone' => 'America/Los_Angeles'
  • 此外,在服务器我已经改变date.timezonephp.ini中,以“美国/洛杉矶”

But any of this updates apply timezone update to the Laravel Eloquent timestamps. This fields created_at and updated_at are handle by Eloquent.

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

I've also update the Ubuntu server timezone using sudo dpkg-reconfigure tzdatabut this update didn't work at all.

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

Edit:I need to have the Laravel Eloquent timestamps working on PST timezone for futures inserts to the DB.

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

Any help will be useful. Thanks.

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

回答by Jeff Lambert

I know this question is a bit dated, but I stumbled upon it when trying to come up with the same solution, and wanted to share how I went about solving it.

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

My advice would be not to change the timezone that the messages are stored in. Store them in the database as UTC. Keeping your storage set to a constant frame of reference and then converting it to whatever timezone you need it displayed in will save you loads of headache over the long run.

我的建议是不要更改存储消息的时区。将它们作为 UTC 存储在数据库中。将您的存储设置为一个恒定的参考框架,然后将其转换为您需要显示的任何时区,从长远来看,这将为您节省大量麻烦。

As an example of one of those headaches, imagine two people trying to coordinate a meeting time in different timezones where one observes DST and one doesn't and you need to display the time in each user's local time. How hard would it be to convert your stored PDT time to say, the America/Cayman (which doesn't observe DST)? And how would you take in account when times are stored in PST vs PDT? How would you know? (Hint: without probably hundreds of lines of extra code just to answer that one question, you won't).

作为其中一个令人头疼的例子,假设两个人试图在不同的时区协调会议时间,其中一个遵守夏令时,另一个没有,您需要以每个用户的本地时间显示时间。将您存储的 PDT 时间转换为美洲/开曼群岛(不遵守夏令时)有多难?当时间存储在 PST 与 PDT 中时,您会如何考虑?你怎么知道的?(提示:如果没有数百行额外的代码来回答这个问题,你就不会)。

To get the time out in the correct timezone, simply add a mutator function on the model itself:

要在正确的时区获得超时,只需在模型本身上添加一个 mutator 函数:

use Carbon\Carbon;

class MyModel extends Eloquent
{
    //  {{{ getCreatedAtAttribute()

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

    //  }}}
}

Now, whenever you do $myModel->created_atit will magically be converted into the correct timezone, but you still keep UTC in your database which definitely has its perks over other timezones for persistent storage.

现在,无论何时,$myModel->created_at它都会神奇地转换为正确的时区,但您仍将 UTC 保留在您的数据库中,这绝对比其他时区更适合持久存储。

Want to let users set their own timezones? Change the function to this:

想让用户设置自己的时区?把函数改成这样:

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

And all of the complexity of changing timezones, taking daying savings into account or not is abstracted away from you and you can forget that it even has to happen.

更改时区的所有复杂性,无论是否考虑日间储蓄都已从您身上抽象出来,您甚至可以忘记它甚至必须发生。

For more information about Laravel mutators / accessors, checkout the documentation.

有关 Laravel 修改器/访问器的更多信息,请查看文档

回答by ghostyu

it's simple,just modify function boot() in AppServiceProvider.php

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

public function boot()
{
    //set local timezone
    date_default_timezone_set('Asia/Shanghai');
}

回答by ?l?

I am not absolutely sure I understand if you want to change the setting of the server for future entries to the database, or if you want to update the current values in your database.

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

If it is the latter, changing your server settings will not effect the current records in the database. If you want to change the values of the existing fields, you can do that with an MySQL command like:

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

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

Where tableis the name of the database table and 2is the offset in hours.

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

回答by Briganti

For Lumen it works with this in .env file:

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

DB_TIMEZONE="+03:00"

DB_TIMEZONE="+03:00"