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

Campos de data e hora do MySQL e horário de verão - como faço referência à hora extra?


Já descobri para meus propósitos. Vou resumir o que aprendi (desculpe, essas notas são detalhadas; elas são tanto para minha referência futura quanto para qualquer outra coisa).

Ao contrário do que eu disse em um dos meus comentários anteriores, os campos DATETIME e TIMESTAMP do comportar-se de forma diferente. Os campos TIMESTAMP (como os documentos indicam) pegam o que você enviar no formato "AAAA-MM-DD hh:mm:ss" e o convertem do seu fuso horário atual para a hora UTC. O inverso acontece de forma transparente sempre que você recupera os dados. Os campos DATETIME não fazem essa conversão. Eles pegam o que você envia e apenas armazenam diretamente.

Nem os tipos de campo DATETIME nem TIMESTAMP podem armazenar dados com precisão em um fuso horário que observa DST . Se você armazenar "2009-11-01 01:30:00", os campos não terão como distinguir qual versão de 1h30 você deseja - a versão -04:00 ou -05:00.

Ok, então devemos armazenar nossos dados em um fuso horário não DST (como UTC). Os campos TIMESTAMP não conseguem lidar com esses dados com precisão por motivos que explicarei:se seu sistema estiver definido para um fuso horário de horário de verão, o que você colocar no TIMESTAMP pode não ser o que você obtém de volta. Mesmo se você enviar dados que já converteu para UTC, ele ainda assumirá que os dados estão em seu fuso horário local e fará outra conversão para UTC. Esta viagem de ida e volta local-para-UTC-volta-para-local imposta por TIMESTAMP é com perdas quando seu fuso horário local observa o horário de verão (desde que "2009-11-01 01:30:00" mapeia para 2 horários possíveis diferentes).

Com DATETIME, você pode armazenar seus dados em qualquer fuso horário que desejar e ter certeza de que receberá de volta o que enviar (você não será forçado a fazer conversões de ida e volta com perdas que os campos TIMESTAMP impõem a você). Portanto, a solução é usar um campo DATETIME e antes de salvar no campo converta do fuso horário do seu sistema para qualquer zona não-DST em que você queira salvá-lo (acho que UTC é provavelmente a melhor opção). Isso permite que você crie a lógica de conversão em sua linguagem de script para que você possa salvar explicitamente o equivalente UTC de "2009-11-01 01:30:00 -04:00" ou ""2009-11-01 01:30:00-05:00".

Outra coisa importante a ser observada é que as funções matemáticas de data/hora do MySQL não funcionam corretamente em torno dos limites do horário de verão se você armazenar suas datas em uma TZ de horário de verão. Portanto, mais uma razão para economizar em UTC.

Em poucas palavras, agora faço isso:

Ao recuperar os dados do banco de dados:


Interprete explicitamente os dados do banco de dados como UTC fora do MySQL para obter um timestamp Unix preciso. Eu uso a função strtotime() do PHP ou sua classe DateTime para isso. Isso não pode ser feito de forma confiável dentro do MySQL usando as funções CONVERT_TZ() ou UNIX_TIMESTAMP() do MySQL porque CONVERT_TZ produzirá apenas um valor 'YYYY-MM-DD hh:mm:ss' que sofre de problemas de ambiguidade, e UNIX_TIMESTAMP() assume sua a entrada está no fuso horário do sistema, não no fuso horário em que os dados foram REALMENTE armazenados (UTC).

Ao armazenar os dados no banco de dados:


Converta sua data para a hora UTC precisa que você deseja fora do MySQL. Por exemplo:com a classe DateTime do PHP, você pode especificar "2009-11-01 1:30:00 EST" distintamente de "2009-11-01 1:30:00 EDT", depois convertê-lo para UTC e salvar o horário UTC correto para o seu campo DATETIME.

Ufa. Muito obrigado pela contribuição e ajuda de todos. Espero que isso economize algumas dores de cabeça para alguém no caminho.

BTW, estou vendo isso no MySQL 5.0.22 e 5.0.27