繁体   English   中英

Laravel中的用户时区问题

[英]User timezones issue in Laravel

我目前将所有日期存储在UTC中。 当用户登录时,它将使用moment.js( moment.tz.guess()函数)以其时区名称(例如America/Toronto )填充隐藏的时区输入,然后在他们登录时更新其在具有所述时区的数据库。

我具有创建的访问者特征,以便显示用户时区中的所有日期。 参见以下代码:

trait Timezone
{
    public function getCreatedAtAttribute($value)
    {
        return $this->timezone($value);
    }

    public function getUpdatedAtAttribute($value)
    {
        return $this->timezone($value);
    }

    public function getDeletedAtAttribute($value)
    {
        return $this->timezone($value);
    }

    // convert date to user timezone
    public function timezone($value)
    {
        $carbon = Carbon::parse($value);

        if (auth()->check()) {
            $carbon->tz(auth()->user()->timezone);
        }

        return $carbon->toDateTimeString();
    }
}

现在我遇到了一个小问题。 我在应用程序中具有报告功能,它具有一个下拉菜单,用户可以在其中选择日期范围,例如“ This WeekLast Week ”等。

我将使用UTC来查询结果,然后将其转换为用户时区。 问题是,对于某些用户而言,根据一天中的时间,一周显示为星期二至星期一,或星期日至星期六,而星期一至星期日。

这是我的代码:

public static function dateStartEnd($date_range)
{
    if ($date_range == 'Today') {
        $start_date = Carbon::now()->startOfDay();
        $end_date = Carbon::now()->endOfDay();
    }
    else if ($date_range == 'Yesterday') {
        $start_date = Carbon::now()->subDay()->startOfDay();
        $end_date = Carbon::now()->subDay()->endOfDay();
    }
    else if ($date_range == 'This Week') {
        $start_date = Carbon::now()->startOfWeek();
        $end_date = Carbon::now()->endOfWeek();
    }
    else if ($date_range == 'Last Week') {
        $start_date = Carbon::now()->subWeek()->startOfWeek();
        $end_date = Carbon::now()->subWeek()->endOfWeek();
    }
    else if ($date_range == 'This Month') {
        $start_date = Carbon::now()->startOfMonth();
        $end_date = Carbon::now()->endOfMonth();
    }
    else if ($date_range == 'Last Month') {
        $start_date = Carbon::now()->subMonth()->startOfMonth();
        $end_date = Carbon::now()->subMonth()->endOfMonth();
    }
    else {
        // All Time
        if ($lead = Lead::orderBy('created_at', 'asc')->first()) {
            $start_date = Carbon::parse($lead->created_at);
        }
        else {
            $start_date = Carbon::now()->startOfDay();
        }

        $end_date = Carbon::now()->endOfDay();
    }

    return [
        'start_date' => $start_date,
        'end_date' => $end_date,
    ];
}

我想知道如何正确执行此操作,以便无论用户时区与UTC进行了比较,它都将使用UTC查询结果,但在用户时区中显示周一至周日。

您可以使用Laravel辅助功能配置来设置时区。 但是,这只会影响您将收到的请求。

config(['app.timezone' => $timezone]);

如果您的目标是更改时区一次并在每个请求上运行,那么如何将更改后的时区保存在数据库或文件中。 然后,编写数据库查询或读取app / config.php中的文件,然后更改文件中index timezone的值。

参考:: 在laravel中动态更改TimeZone

我最终为localutc开始和结束日期创建了单独的返回属性。

这是我的代码现在的样子:

public static function dateStartEnd($date_range, $date_from, $date_to)
{
    if ($date_range == 'Today') {
        $start_local = Carbon::now(auth()->user()->timezone)->startOfDay();
        $end_local = Carbon::now(auth()->user()->timezone)->endOfDay();
    }
    else if ($date_range == 'Yesterday') {
        $start_local = Carbon::now(auth()->user()->timezone)->subDay()->startOfDay();
        $end_local = Carbon::now(auth()->user()->timezone)->subDay()->endOfDay();
    }
    else if ($date_range == 'This Week') {
        $start_local = Carbon::now(auth()->user()->timezone)->startOfWeek();
        $end_local = Carbon::now(auth()->user()->timezone)->endOfWeek();
    }
    else if ($date_range == 'Last Week') {
        $start_local = Carbon::now(auth()->user()->timezone)->subWeek()->startOfWeek();
        $end_local = Carbon::now(auth()->user()->timezone)->subWeek()->endOfWeek();
    }
    else if ($date_range == 'This Month') {
        $start_local = Carbon::now(auth()->user()->timezone)->startOfMonth();
        $end_local = Carbon::now(auth()->user()->timezone)->endOfMonth();
    }
    else if ($date_range == 'Last Month') {
        $start_local = Carbon::now(auth()->user()->timezone)->subMonth()->startOfMonth();
        $end_local = Carbon::now(auth()->user()->timezone)->subMonth()->endOfMonth();
    }
    else if ($date_range == 'Custom') {
        $start_local = Carbon::parse($date_from, auth()->user()->timezone)->startOfDay();
        $end_local = Carbon::parse($date_to, auth()->user()->timezone)->endOfDay();
    }
    else {
        // All Time
        if ($lead = Lead::orderBy('created_at', 'asc')->first()) {
            $start_local = Carbon::parse($lead->created_at, auth()->user()->timezone);
        }
        else {
            $start_local = Carbon::now(auth()->user()->timezone)->startOfDay();
        }

        $end_local = Carbon::now(auth()->user()->timezone)->endOfDay();
    }

    return [
        'start_local' => $start_local,
        'start_utc' => $start_local->copy()->timezone(config('app.timezone')),
        'end_local' => $end_local,
        'end_utc' => $end_local->copy()->timezone(config('app.timezone')),
    ];
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM