настройка вывода массива для пользовательского часового пояса

Важная информация, чтобы знать:

  • База данных хранит смещение часового пояса пользователя в виде цифры (например, у пользователя в 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 означает среду в 23:00. В 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;
}
}

Теперь я пытаюсь найти способ, которым я могу настроить данные массива, чтобы отразить смещение часового пояса пользователя. Поэтому информация должна как-то обрабатываться до того, как она достигнет цикла foreach с регистром коммутатора. Кто-нибудь когда-нибудь имел дело с этим вопросом раньше? Спасибо!

0

Решение

В этом примере я буду использовать эти переменные:

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

Заполните массив именами дней недели, связанными с вашей недельной системой (в этом примере 0 = понедельник, 6 = воскресенье):

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

Создайте новый объект UTC DateTime:

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

Изменить TimeZone:

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

и у вас есть дата в нужном часовом поясе.

Чтобы использовать название дня недели:

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

Чтобы использовать 0-24 часа (без начального нуля):

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

Вы можете найти полный доступный выходной формат объявления date() раздел руководства по PHP.

0

Другие решения

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 — плохая идея. Вы не сможете правильно учесть летнее время. Лучше использовать названный часовой пояс или местоположение.

0

По вопросам рекламы [email protected]