Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

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

  • I update the config/application.php to 'timezone' => 'America/Los_Angeles'
  • Also in the server I've change the date.timezone in php.ini to 'America/Los_Angeles'

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

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

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

Any help will be useful. Thanks.

like image 633
larc000 Avatar asked Sep 29 '13 23:09

larc000


3 Answers

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.

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).

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

use Carbon\Carbon;

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

Now, whenever you do $myModel->created_at it 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.

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 daylight 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.

like image 100
Jeff Lambert Avatar answered Nov 10 '22 20:11

Jeff Lambert


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:

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

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

like image 32
ılǝ Avatar answered Nov 10 '22 21:11

ılǝ


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

public function boot()
{
    //set local timezone
    date_default_timezone_set('Asia/Shanghai');
}
like image 2
ghostyu Avatar answered Nov 10 '22 21:11

ghostyu