Timezone louca no PHP

Acredito ter encontrado uma espécie de bug bizarro do PHP versões 5.1.x em servidores Linux.

O problema: O PHP 5.1.x não simplesmente pega a data/hora do sistema. Ele pega a timezone do sistema e calcula a hora a partir disso. Até aí, beleza. Estava tudo indo bem até domingo, quando DEVERÍAMOS ter entrado em horário de verão, mas não entramos por questão de decretos. Os sistemas linux, corretamente configurados, não entraram. Mas os PHPs surtados olharam a timezone America/Sao_Paulo do sistema, olharam a data, e resolveram que estão em horário de verão. Resultado: a data do sistema está correta, mas as aplicações PHP apresentam hora errada (entraram em horário de verão independente da hora do sistema).

UPDATE!!!!!!!!! AGORA SIM!!!!!!
A solução correta: Segundo o blog do TaQ, instalar o timezonedb. Depois de lutar pra compilar o timezonedb, corrigi uns symlinks e bingo, funcionou. Ou seja: é isso mesmo. Grande timezonedb, conserta o problema. Para instalá-lo, você vai precisar de uma versão recente do PHP, do pacote php-dev da sua distribuição, php-pear, e, eventualmente, de alguma experiência em troubleshooting. ;) Mas, no final, vai funcionar.

O workaround (nome bonito pra gambiarra): No php.ini das versões 5.1.x, existe uma opção date.timezone, que deve ser descomentada e alterada para GMT -3:00. Por causa das bizarrices do PHP, a opção de timezone relativa à zona GMT -3:00 (usada no Brasil sem horário de verão), é Etc/GMT+3 - assim mesmo, com sinal de mais. Portanto, a linha em questão ficará assim:
date.timezone = Etc/GMT+3

O problema, como toda gambiarra tem, é que isso terá que ser alterado manualmente (ou por um script, claro, mas continua sendo “feio”) no dia 5/11 e novamente no dia 25/2, quando, respectivamente, começa e termina o horário de verão.

Gostaria de lembrar que o problema ocorre mesmo nas versões mais recentes do PHP. Se alguém souber de alguma dica, eu agradeço. Eu realmente não tenho idéia de como resolver isso de uma maneira “bonita” - Agradeço muito a dica do Dirceu, que vai certamente resolver meu problema, é só uma questão de tempo agora.

14 comments:

  1. Dirceu Pereira Tiegs, 19. October 2006, 11:50

    Oi Renata,

    Dê uma olhada nesse post do TaQ que fala sobre esse mesmo problema:

    http://eustaquiorangel.com/blog/show/308

    Um abraço

     
  2. Renata, 19. October 2006, 12:52

    Linda essa solução do TaQ, SE o módulo compilasse aqui. preciso descobrir porque diabos não tenho o arquivo timelib_config.h, mas mantê-los-ei informados. Muito obrigada pela informação, Dirceu!

     
  3. Juliano, 25. October 2006, 17:17

    Oi Renata, como foi os symlinks que você corrigiu para compilar o timezonedb?

     
  4. Guto, 7. November 2006, 16:23

    altere o timezone do php.ini assim:
    data.timezone = America/Fortaleza ou America/Sao_Paulo ou America/Bahia etc.
    Esses valores vc encontra aqui:
    http://www.php.net/manual/en/timezones.america.php

     
  5. Renata, 7. November 2006, 16:28

    Guto, isso sozinho não estava funcionando a partir do PHP 5.1.x, porque ele pegava a timezone mas entrou em horário de verão antes da hora certa. Sacou o problema?

     
  6. JP, 12. February 2007, 9:48

    Olá,

    Muito úteis as dicas de vocês. O problema voltou a ocorrer neste final de semana (11/02/2007), com o teórico término do horário de verão (foi prorrogado por decreto). Aqui no meu servidor (Win XP com PHP 5.1.2) a solução mais simples foi colocar date.timezone = Etc/GMT 3 no PHP.ini.

    Obrigado.

     
  7. Fischer, 11. October 2007, 17:29

    Instructions on how to update PHP’s timezonedb

    http://fischer.tecnologia.ws/en/node/1

     
  8. Julio, 10. January 2008, 9:10

    Sabia que era coisa do php! ¬¬

    Valeu renata!

    =D

     
  9. João Paulo, 21. January 2008, 13:56

    eu tive o mesmo problema mas optei por um método alternativo e muito eficaz, talvez um pouco mais trabalhoso que o simples date().
    //atualiza o banco de dados com hora e data atual e seleciona os mesmos que foram adicionados agora
    mysql_query(”UPDATE IGNORE now SET hora=CURRENT_TIME,data=CURRENT_DATE”);
    $SQLnow = mysql_fetch_array(mysql_query(”SELECT hora,data FROM now”));

    para usar basta vc se beneficiar do explode() que é possível fazer quase todas opções do date().

     
  10. Frank, 18. February 2008, 17:28

    Domo arigatou gossaimasta ^ ^!!!

    No ubuntu nem precisa compilar nada, é só colocar a linha que a Renata falou.

    Valeu Renata! ;-)

     
  11. phper, 3. August 2008, 0:17

    date_default_timezone_set(’Etc/GMT+3′);

    (:

     
  12. tatsu, 14. August 2008, 18:11

    recompilar o timezone(zic), não seria mais fácil?

     
  13. Victor Benincasa - Netbit Internet, 21. October 2008, 19:30

    O PHP utiliza um sistema de timezones diferente do sistema operacional, então, se desatualizado, pode considerar que o horário de verão brasileiro (GMT -0200) tem início ou término na data errada.

    Assim como é necessário atualizar o arquivo de timezone do sistema operacional (/usr/share/zoneinfo/Brazil) para que ele entre no horário de verão no dia correto, é necessário atualizar o sistema de timezone do PHP.

    Esse banco de dados de timezones é provido pelo pacote PECL TIMEZONEDB (http://pecl.php.net/package/timezonedb/), basta atualizá-lo para a última versão (2008.8). É possível consultar a versão em uso através da função phpinfo(), item “Olson Timezone Database Version”.

    A forma mais simples de atualização é utilizando o próprio PECL:

    $ pecl install timezonedb

    Obs. É necessário utilizar o PECL como root, que exige permissão de execução em /tmp por padrão.

    Eu me impressiono como tem gente ainda comentando um post meu de 2006, mega desatualizado, mas sim, é isso mesmo.

     
  14. Techfree » O Ocomon e o horário de verão (Pingback), 6. November 2008, 18:09
     

    [...] essa solução seja para a versão antiga do PHP, pois após uma busca na internet, encontrei no blog da Renata uma “gambiarra” para resolver meu [...]

     

Write a comment:

Bad Behavior has blocked 743 access attempts in the last 7 days.