Важная информация, чтобы знать:
База данных хранит смещение часового пояса пользователя в виде цифры (например, у пользователя в 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 с регистром коммутатора. Кто-нибудь когда-нибудь имел дело с этим вопросом раньше? Спасибо!
В этом примере я буду использовать эти переменные:
$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.
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 — плохая идея. Вы не сможете правильно учесть летнее время. Лучше использовать названный часовой пояс или местоположение.