Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Usando fusos horários em um aplicativo web PHP


Eu lidei com essa situação extensivamente em um aplicativo PHP/MySQL que escrevi para um operador de jato particular há pouco mais de um ano. Existem diferentes estratégias para lidar com fusos horários nessas duas plataformas, mas vou explicar como fiz isso. Eu configuro o servidor MySQL para UTC e executo cada script PHP no fuso horário que o usuário especifica durante o processo de inscrição para o perfil do usuário.

MySQL e PHP (PHP 5.2 e superior) possuem tipos de dados de data e hora nativos. O datetime do MySQL é um tipo de dados primitivo, enquanto o PHP 5.2 e superior oferece o classe DateTime . O tipo de dados datetime do MySQL não inclui metadados para o fuso horário, mas um objeto PHP DateTime sempre inclui um fuso horário. Se o construtor de data e hora do PHP não especificar o fuso horário opcional no segundo argumento, o construtor de data e hora do PHP usará a variável de ambiente php.

Tanto o MySQL quanto o PHP têm o fuso horário padrão definido nos arquivos de configuração. O MySQL usa o datetime definido no arquivo de configuração para cada conexão db, a menos que o usuário especifique um fuso horário diferente após a conexão ser iniciada com o comando SET time_zone = [timezone]; . O PHP também define uma variável de ambiente de fuso horário para cada script usando o fuso horário definido no arquivo de configuração do servidor, e essa variável de ambiente pode ser substituída usando a função PHP date_default_timezone_set() após o início do script.

A classe PHP DateTime tem uma propriedade chamada timezone , que é um objeto PHP DateTimeZone . O objeto DateTimeZone é especificado usando uma string para o fuso horário exato. A lista de fusos horários é abrangente, com centenas de fusos horários individuais em todo o mundo. Os fusos horários do PHP contabilizarão o horário de verão automaticamente.

Quando o usuário gera um datetime no aplicativo Web, construa um objeto datetime PHP no fuso horário do perfil do usuário. Em seguida, use o setTimezone método para modificar o objeto DateTime para o fuso horário UTC. Agora você tem a data e hora do usuário em UTC e pode armazenar o valor no banco de dados. Use o format DateTime método para expressar os dados como uma string no formato aceito pelo MySQL.

Assim, o usuário gera um datetime e você cria um objeto datetime PHP no fuso horário especificado pelo usuário:
// set using an include file for user profile
$user_timezone = new DateTimeZone('America/New_York'); 

// 1st arg in format accepted by PHP strtotime
$date_object1 = new DateTime('8/9/2012 5:19 PM', $user_timezone); 
$date_object1->setTimezone(new DateTimeZone('UTC'));
$formated_string = $date_object1->format('Y-m-d H:i:s');
$query_string = "INSERT INTO `t_table1` (`datetime1`) VALUES('$formated_string')";

Ao recuperar o valor do banco de dados, construa em UTC e converta para o fuso horário do usuário.
$query_string = "SELECT `datetime1` FROM `t_table1`";
$date_object1 = new DateTime($datetime_string_from_mysql, new DateTimeZone('UTC'));
$date_object1->setTimezone($user_timezone);
$string_for_display_in_application = $date_object1->format('m/d/Y g:i a');

Usando esse método, seus valores de data e hora são sempre armazenados em UTC dentro do banco de dados, e o usuário sempre experimenta os valores no fuso horário de seu perfil. O PHP corrigirá o horário de verão, se necessário, para cada fuso horário.

Uma pegadinha:Esta explicação não cobre o tipo de dados timestamp do MySQL. Eu recomendo usar o tipo de data datetime do MySQL para armazenar valores de data e hora, não o tipo de dados timestamp. O tipo de dados timestamp é abordado no manual aqui .

Editar: Você pode produzir um array contendo cada string de fuso horário PHP usando listIdentifiers , que é um método estático da classe DateTimeZone.