Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Guilherme Luiz

Encontrar diferença de horas entre fusos

Recommended Posts

Olá Pessoal,

 

Tenho a seguinte necessidade:

 

Encontrar a diferença, em horas, entre dois fusos horários indiferente se a diferença é para maior ou menor.

 

Qual a utilidade?

Tenho um projeto onde o usuario precisa indicar o seu fuso horario para realizar uma determinada ação. Até ai ok.

Entretanto, este meu usuario poderá estar num fuso diferente da minha aplicação.

 

Tendo dito o cenário é o seguinte:

Minha aplicação está num servidor de fuso Espanha/Madrid e meu usuário está no fuso America/Sao_paulo.

Neste exemplo eu tenho uma diferença e 5 horas, onde o usuário em America/Sao_paulo está a 5 horas antes do horario do meu servidor, ou seja, usuário está logado as 1500 do dia 23/08 e no meu servidor todas as informações estão sendo processadas as 20:00 do dia 23/08..

 

Então para facilitar a vida deste meu usuário, ele vai indicar o seu fuso e o meu sistema fara os calculos para que, de acordo com a diferença entre os fusos, meu servidor processe tudo baseado no horario local de Europe/Madrid.

 

Parece simples mas chegarei a um momento onde terei usuarios de diversos fusos realizando ações em minha aplicação.

 

Deste modo eu tenho rabisquei o seguinte código

date_default_timezone_set('Europe/Madrid'); //seto como default o fuso do meu servidor
$datek = date('H'); //salvo na variavel a hora do meu servidor
echo "<br>".$datek."<br>"; //imprimo por imprimir
date_default_timezone_set('America/Sao_paulo'); //seto um novo default com o fuso do meu usuario
$datep = date('H'); /salvo na variavel a hora baseada no fuso do usuario
echo "<br>".$datep."<br>";  //imprimo por imprimir
echo "<br>".(($datek - $datep)+24)."<br>"; //imprimo e o resultado é 5

Neste modo com o fuso America/Sao_paulo o resultado é 5, ou seja, correto, logo me atende!

Agora se o meu usuario tiver o fuso Europe/Lisbon, onde a diferença é 1 hora a menos entre Lisboa e Madrid (por exemplo Lisboa 03:00AM - MAdrid 04:00AM)  o resultado deste script é 25

 

Alguma sugestão de melhoria ou alguma outra função que me traga essa diferença de hora entre dois fusos?

Compartilhar este post


Link para o post
Compartilhar em outros sites

tem certeza que vais precisar calcular a diferença? não seria só ter a lista de fusos pro usuário escolher? aí já vai ter o fuso correto sem precisar calcular...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sistemas com múltiplos fuso horários tendem  a unificar os horários salvos em GMT (Greenwich Mean Time) ou UTC 0, para que cada usuário possua seu próprio fuso horário e os seus registros estejam unificados.

 

Quanto a forma de exibição, a biblioteca Date/Time consegue resolver isso pra ti de forma bem flexível:

$timeZone = new DateTimeZone("America/Sao_Paulo");
$UTC = new DateTimeZone("UTC");
$date = new DateTime("2017-08-24 10:15:00", $timeZone );
$date->setTimezone( $UTC );
echo $date->format('Y-m-d H:i:s');

Saída

Citar

2017-08-24 13:15:00

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
16 horas atrás, marsolim disse:

tem certeza que vais precisar calcular a diferença? não seria só ter a lista de fusos pro usuário escolher? aí já vai ter o fuso correto sem precisar calcular...

 

Preciso sabe porque?

Porque a aplicação que estou trabalhando não tem "inteligência" para interpretar timezones distintos então eu preciso dessa "gambiarra"

 

Vamos supor

 

timezone Europe/Madrid

Neste momento são 21:32PM

 

timezone America/Sao_paulo
Neste momento são 16:32PM

 

Diferença 5 HORAS

 

Por mais que eu indique a minha aplicação que está em Europe/Madrid que o horario que está recebendo está vindo de um timezone distinto, a aplicação sempre gera suas ações baseadas no seu timezone ignorando o timezone do usuario mesmo quando indicado.

 

Deste modo o que eu preciso fazer é identificar a diferença de horas entre os dois timezone.

Encontrada essa diferença eu somo ou subtraio esse valor na hora do cliente para mandar a minha aplicação o horario correto.

 

Vamos supor que eu tenho uma ação de agendamento

O meu usuario em time America/Sao_paulo quer agendar uma ação para as 17h.

Quando mando essa info para a aplicação, a aplicação não agenda a ação e a executa imediatamente. Porque? Porque ela ignora a indicação do timezone e trata tudo no timezone local.

 

Neste caso eu preciso pegar a hora indicada pelo meu usuario - 17h - e somar 5 horas (diferença entre os dois fusos).

Deste modo a ação de agendamento ao meu servidor vai chegar para as 22h (17h + 5h) e assim, somente assim, minha aplicação faz o agendamento do comando.

 

Em resumo, minha aplicação somente processa dados de data em seu timezone local ignorando o timezone do usuario.

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

o script do Gabriel Heming te serve como uma luva acho eu pois ele faz pegar a hora de uma tz e converter na outra sem precisar mais nada. acho que é o que precisa

Compartilhar este post


Link para o post
Compartilhar em outros sites

Segue o caminho encontrado para ter a Diferença entre dois fusos (em hora) 

function tzDifference($tz){
  
  //PUXO A HORA ATUAL DE ACORDO COM O TZ INFORMADO PELO USUARIO
  $date = new DateTime('now', new DateTimeZone($tz) );
  $date = strtotime($date->format('H:i:s'));

  //PUXO A HORA ATUAL DA MINHA APLICAÇÃO DE ACORDO COM O MEU TZ FIXO
  $date2 = new DateTime('now', new DateTimeZone('Europe/Madrid') );
  $date2 = strtotime($date2->format('H:i:s'));
  
  //CALCULO AS DATAS E IMPRIMO O RESULTADO
  $diffHours = round(($date2 - $date) / 3600);
  switch($diffHours){
    case $diffHours > 0:
      $x = '+'.$diffHours.'hours';
      break;
    default:
      $x = $diffHours.'hours';
      break;
  }
  return $x;

  //EXEMPLO DE SAIDA: '+5Hours' ou '-5hours'
}

E tendo esse resultado eu aplico assim:

$horaDiferenca = tzDifference('America/Sao_paulo'); //aqui o meu usuario indica num select box qual o timezone dele
$dataEnvio     = date("Y-m-d H:i:s", strtotime($programa[0]['data'].$programa[0]['hora'].$horaDiferenca));

Porque tudo isso?:

Porque a aplicação API que estou chamando trabalha unica e exclusivamente via TZ Europe/Madrid e para que ações programadas/agendadas funcionassem corretamente, era preciso encontrar a diferença em horas de acordo com o TZ do API com o TZ do meu usuario e indicar a hora ao API de acordo com a hora do TZ dele, que é Europe/Madrid

 

Espero que ajude alguem e se alguem tiver mais sugestões de melhoria, fico aberto a opiniões :)

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por Nightmare SEP
      Bom dia,
       
      Desde esse último final de semana, que os computadores atualizaram a hora para o horário de verão, eu não consigo corrigir a hora no meu servidor localhost aqui.
       
      A data do servidor está correta (08:47 agora). No php.ini o date.timezone está igual a "America/Sao_Paulo" e mesmo assim no sistema está mostrando o horário 09:47.
       
      O que mais posso alterar?
    • Por Rodolfo17
      Quando dou o comando : echo ini.get('date.timezone') . "<br>"; não aparece nada, já configurei no php.ini e nada, também já coloquei o default no código e nada também. Alguém pode me ajudar?
    • Por sergionpinheiro
      Boa noite galera,
       
      Estou desenvolvendo um sistema de leilão que está tudo ok.
       
      Gostaria de saber se existe uma horário universal em php, onde todos os usuários do planeta tenham o mesmo tempo restante para o término do leilão.
       
      Atualmente aqui no Brasil o leilão termina em x tempo, mas lá nos EUA é outro tempo.
       
      Tem como unificar isso?
       
      Outra coisa, cada vez que um usuário der um lance e faltar menos de 5 minutos para terminar, ele fará um acréscimo de mais 5min no tempo restante.
       
      Fiz dessa maneira:
       
      $data_atual = $row_leiloes['final']; $nova_data = date('Y-m-d H:i:s', strtotime($data_atual . '+5 minutes')); Lembrando que essa nova data, terá quer ser padrão para todos os usuários do planeta.  
      Fico no aguardo.
    • Por marlaaragao
      Boa tarde,
       
      Estou trabalhando em um sistema e ele tem uma tabela que seta algumas configurações de usuário. Uma dessas configurações é timezone. Mas como mudar as datas mostradas para cada usuário de acordo com a timezone escolhida por ele? Isso é possível?
       
      Creio que não é possível fazer isso utilizando date_default_timezone_set, pois ela vai setar a timezone para aplicação inteira. Gostaria de saber se existe um jeito de antes de mostrar determinada data, ela possa ser modificada para a timezone do cliente e somente depois mostrada na tela.
       
      Obrigada!
    • Por Dorian Neto
      Fala galera, blz?
       
      Tenho uma dúvida simples, mas que sugou minhas forças.
       
      Estou desenvolvendo um site em wordpress que em um das áreas precisei montar um calendário, e pra isso utilizei a função cal_days_in_month(). Até ai blz, consegui montar o calendário direitinho e tals. O grande problema é que a data retornada pela função date() não fica em português de jeito nenhum! Vei, eu fiz de tudo, mexi no php.ini, defini timezone em tempo de execução etc.
       
      Resumo da história: me rendi e utilizei o strftime() com setlocale(). Dessa forma deu certo, mas gostaria de saber se alguém já passou por esse tipo de problema, pois gostaria muito de saber o motivo da função date não pegar o timezone.
       
      Desde ja agradeço!
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.