【问题标题】:What is the best way to change the user's timezone in Laravel 4?在 Laravel 4 中更改用户时区的最佳方法是什么?
【发布时间】:2013-07-01 12:46:35
【问题描述】:

目前,我已将用户时区保存在他们的数据库行中,每次打印日期时,我都会将其转换为用户的时区。我怎样才能以干燥的方式做到这一点?

我是否应该覆盖 Eloquent 返回 Carbon DateTime 对象的位置。如果是这样,我应该把它放在下面的特征中,这样我只需要写一次吗?

<?php

use Carbon\Carbon;
use Illuminate\Database\Eloquent;

trait ConvertTimeZone {
/**
 * Return a timestamp as DateTime object.
 *
 * @param  mixed  $value
 * @return DateTime
 */
protected function asDateTime($value)
{
    // If this value is an integer, we will assume it is a UNIX timestamp's value
    // and format a Carbon object from this timestamp. This allows flexibility
    // when defining your date fields as they might be UNIX timestamps here.
    if (is_numeric($value))
    {
        return Carbon::createFromTimestamp($value);
    }

    // If the value is in simply year, month, day format, we will instantiate the
    // Carbon instances from that fomrat. Again, this provides for simple date
    // fields on the database, while still supporting Carbonized conversion.
    elseif (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $value))
    {
        return Carbon::createFromFormat('Y-m-d', $value);
    }

    // Finally, we will just assume this date is in the format used by default on
    // the database connection and use that format to create the Carbon object
    // that is returned back out to the developers after we convert it here.
    elseif ( ! $value instanceof DateTime)
    {
        $format = $this->getDateFormat();

        $timezone = \Auth::user()->timezone;

        return Carbon::createFromFormat($format, $value, $timezone);
    }

    return Carbon::instance($value);
}

}

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    我会创建一个BaseModel 类,扩展Eloquent,我会从中扩展我需要此类功能的模型。只需要记住检查用户是否登录,这样我们就可以得到它的时区。示例:

    models/BaseModel.php

    class BaseModel extends Illuminate\Database\Eloquent\Model {
    
        protected function asDateTime($value) {
    
            // If Carbon receives null, it knows to use the default timezone
            $tz = null;
    
            // If the user is logged in, get it's timezone
            if (Auth::check()) {
                $tz = Auth::user()->timezone;
            }
    
            // If this value is an integer, we will assume it is a UNIX timestamp's value
            // and format a Carbon object from this timestamp. This allows flexibility
            // when defining your date fields as they might be UNIX timestamps here.
            if (is_numeric($value)) {
                return Carbon::createFromTimestamp($value, $tz);
            }
    
            // If the value is in simply year, month, day format, we will instantiate the
            // Carbon instances from that fomrat. Again, this provides for simple date
            // fields on the database, while still supporting Carbonized conversion.
            elseif (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $value)) {
                return Carbon::createFromFormat('Y-m-d', $value, $tz);
            }
    
            // Finally, we will just assume this date is in the format used by default on
            // the database connection and use that format to create the Carbon object
            // that is returned back out to the developers after we convert it here.
            elseif ( ! $value instanceof DateTime) {
                $format = $this->getDateFormat();
    
                return Carbon::createFromFormat($format, $value, $tz);
            }
    
            return Carbon::instance($value);
        }
    }
    

    models/User.php

    class User extends BaseModel {
        // ...
    }
    

    【讨论】:

    • 你能告诉我为什么扩展 BaseModel 比使用 trait 更好吗?谢谢
    • 这并不是说它更好,特质的东西实际上非常好,并且可以正常工作。这就是我自从开始使用 Laravel 以来一直在做的事情,我想我可以分享它。当然,这样做的唯一优点是它不需要 PHP 5.4.0,但这可能不是主要问题。
    • 最好只使用一个mutator。
    • @SajanParikh 但是你需要为你想要的每个日期属性编写一个mutator。
    猜你喜欢
    • 2021-06-30
    • 2018-07-16
    • 2016-11-12
    • 2019-08-19
    • 1970-01-01
    • 1970-01-01
    • 2015-09-16
    • 2015-01-18
    • 2016-09-17
    相关资源
    最近更新 更多