【问题标题】:adjusting array output for user timezone调整用户时区的数组输出
【发布时间】:2016-07-08 09:43:58
【问题描述】:

需要了解的重要信息:

  • 数据库将用户时区偏移存储为数字(例如:EST 中的用户有一个值为 -4 的时区列

  • 服务器时间为 UTC

我正在返回一个查询,其中包含按工作日和小时分组的聚合数据,希望将其显示在热图上。

到目前为止,这就是我所拥有的。

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

$week_data = DB::select('SELECT COUNT(id) as total, WEEKDAY(created_at) AS week_day ,HOUR(created_at) as hours 
FROM messages
GROUP BY week_day, hours');

举几个例子:

在此示例中,“week_day”是一周中某天的数字表示(0 = 星期一,6 = 星期日) 小时是一天中小时的数字表示(24 小时格式)

目前,具有 week_day->2 和 hours->23 的对象表示星期三晚上 11 点 IN UTC

获得查询结果后,我使用 foreach 循环分离数据,其中 $new_array 是我之前实例化的变量(未显示)

 foreach ($week_data as $data)
    {
        if ($data->week_day == 0)
        {
            $new_array['Monday'][$data->hours] = $data;
        }
        elseif ($data->week_day == 1)
        {
            $new_array['Tuesday'][$data->hours] = $data;
        }elseif ($data->week_day == 2)
        {
            $new_array['Wednesday'][$data->hours] = $data;
        } elseif ($data->week_day == 3)
        {
            $new_array['Thursday'][$data->hours] = $data;
        }
        elseif ($data->week_day == 4)
        {
            $new_array['Friday'][$data->hours] = $data;
        }
        elseif ($data->week_day == 5)
        {
            $new_array['Saturday'][$data->hours] = $data;
        }
        elseif ($data->week_day == 6)
        {
            $new_array['Sunday'][$data->hours] = $data;
        }
    }

现在,我正在尝试找到一种方法来调整数组数据以反映用户时区的偏移量。因此,信息应该在到达带有 switch 案例的 foreach 循环之前以某种方式进行处理。以前有没有人处理过这个问题?谢谢!

【问题讨论】:

    标签: php arrays timezone timezone-offset php-carbon


    【解决方案1】:

    在本例中,我将使用这些变量:

    $week_day = 1;
    $hours    = 23;
    $TimeZone = -4;
    

    用与您的周系统一致的星期名称填充一个数组(此示例有 0=Monday, 6=Sunday ):

    $weekdays = [ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' ];
    

    创建新的 UTC DateTime 对象:

    $date = new Datetime( "{$weekdays[$week_day]}, {$hours}:00 UTC" );
    

    更改时区:

    $date->setTimezone( new DateTimeZone($TimeZone) );
    

    并且您的日期位于所需的时区。

    使用工作日名称:

    $weekday_name = $date->format( 'l' );
    

    要使用 0-24 小时(不带前导零):

    $hour = $date->format( 'G' );
    

    您可以在 php 手册的date() 部分找到完整的可用输出格式。

    【讨论】:

      【解决方案2】:

      MySQL 的CONVERT_TZ 函数将DATETIME 值从一个时区转换为另一个时区。如果您在选择数据时使用此功能,则根本不需要更改 PHP 代码。

      如果用户输入了$timezone,则需要编辑此代码以防止 SQL 注入。我不熟悉你的数据库抽象库,否则我会为你做的。

      $timezone = Auth::user()->timezone;
      
      $week_data = DB::select("
          SELECT COUNT(id) as total,
                 WEEKDAY(CONVERT_TZ(created_at, '+0:00', '$timezone:00')) AS week_day,
                 HOUR(CONVERT_TZ(created_at, '+0:00', '$timezone:00')) AS hours 
          FROM messages
          GROUP BY week_day, hours");
      

      但是,将用户的时区存储为距 UTC 的小时数是一个坏主意。您将无法正确计算夏令时。最好使用命名的时区或位置。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-09
        • 1970-01-01
        • 2014-04-11
        • 1970-01-01
        • 2022-07-12
        • 1970-01-01
        相关资源
        最近更新 更多