[英]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 Week
, Last 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的值。
我最终为local
和utc
开始和结束日期创建了单独的返回属性。
这是我的代码现在的样子:
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.