Jump to content
Alcaponepone

Diferença entre datas Array

Recommended Posts

Boa tarde

 

 estou fazendo um trabalho de TCC preciso saber a o tempo total que uma lampada ficou ligada usando a tabela de dados Mysql que criei que grava a hora que foi acionada e des-acionada.

para saber o horário que a lampada ficou ligada preciso da diferença de Datatime. Estou retornando as datas liga e desligada em array() mais não consigo calcular pois acho que array esta gravando os dados como string;

 

 

sugestões são bem aceitas,

 

 

Obrigado

 

$sql = "SELECT lamp_id, lamp_data, lamp_estado FROM lampadas_rel where lamp_estado=0 ORDER BY lamp_sec";
$result = $conn->query($sql);
    if ($result->num_rows > 0) {
        $i=0;
        while($row = $result->fetch_assoc()){
            $desli[]= Date('d/m/Y H:i:s',  strtotime($row["lamp_data"]));
         
        }
        print_r($desli);
        
        
    }
    
echo "<br>";
    
$sql = "SELECT lamp_id, lamp_data, lamp_estado FROM lampadas_rel where lamp_estado=1 ORDER BY lamp_sec";
$result = $conn->query($sql);
    if ($result->num_rows > 0) {
        $i=0;
        while($row = $result->fetch_assoc()){
            $liga[]= Date('d/m/Y H:i:s',  strtotime($row["lamp_data"]));
         
        }
        print_r($liga);
        
        
    }    
    
$dtar = $liga - $desli;

 

Edited by Gabriel Heming
adicionar marcação de código

Share this post


Link to post
Share on other sites

lamp_id é a chave primária da tabela ou identifica lampadas distintas e lamp_sec é uma sequencia incremental, ou ele agrupa o evento de ligar e desligar, ou identifica lampadas distintas?

 

Se for possível e do seu interesse publique o esquema da tabela lampadas_rel junto de alguns dados de exemplo, pois talvez você possa conseguir essa informação diretamente do banco, seja com uma consulta que calcule o tempo entre cada registro ou pré calculando via triggers.

Share this post


Link to post
Share on other sites

Partindo do principio de que a tabela armazena somente o estado de uma única lampada você poderia recuperar a duração de cada intervalo em que a lampada ficou ligada com uma seguintes consultas.

/*Retorna a diferença em segundos, você deve tratar a formação na sua aplicação*/
SELECT
  l_ligada.lamp_id AS ligada_id,
  MIN(l_desligada.lamp_id) AS desligada_id,
  MIN(UNIX_TIMESTAMP(IFNULL(l_desligada.lamp_data, CURRENT_TIMESTAMP)) - UNIX_TIMESTAMP(l_ligada.lamp_data)) as tempo_ligada
FROM
  `lampadas_rel` AS l_ligada
LEFT JOIN
  lampadas_rel AS l_desligada
ON
  l_desligada.lamp_id > l_ligada.lamp_id AND l_desligada.lamp_estado = 0
WHERE
  l_ligada.lamp_estado = 1
GROUP BY
  l_ligada.lamp_id
ORDER BY
  l_ligada.lamp_id ASC

/*Ou, retorna a diferença como TIME o valor maximo é 838:59:59 https://dev.mysql.com/doc/refman/5.7/en/time.html)*/
SELECT
  l_ligada.lamp_id AS ligada_id,
  MIN(l_desligada.lamp_id) AS desligada_id,
  SEC_TO_TIME(MIN(UNIX_TIMESTAMP(IFNULL(l_desligada.lamp_data, CURRENT_TIMESTAMP)) - UNIX_TIMESTAMP(l_ligada.lamp_data))) as tempo_ligada
FROM
  `lampadas_rel` AS l_ligada
LEFT JOIN
  lampadas_rel AS l_desligada
ON
  l_desligada.lamp_id > l_ligada.lamp_id AND l_desligada.lamp_estado = 0
WHERE
  l_ligada.lamp_estado = 1
GROUP BY
  l_ligada.lamp_id
ORDER BY
  l_ligada.lamp_id ASC

/*Ou, retorna a diferença como TIME o valor maximo é 838:59:59 https://dev.mysql.com/doc/refman/5.7/en/time.html)*/
SELECT
  l_ligada.lamp_id AS ligada_id,
  MIN(l_desligada.lamp_id) AS desligada_id,
  MIN(TIMEDIFF(IFNULL(l_desligada.lamp_data, CURRENT_TIMESTAMP), l_ligada.lamp_data)) as tempo_ligada
FROM
  `lampadas_rel` AS l_ligada
LEFT JOIN
  lampadas_rel AS l_desligada
ON
  l_desligada.lamp_id > l_ligada.lamp_id AND l_desligada.lamp_estado = 0
WHERE
  l_ligada.lamp_estado = 1
GROUP BY
  l_ligada.lamp_id
ORDER BY
  l_ligada.lamp_id ASC

Você pode testar as consultas acima em http://sqlfiddle.com/#!9/bfe330/5.

 

Partindo de uma consulta semelhante você poderia calcular a diferença diretamente no PHP.

SELECT
  l_ligada.lamp_id AS id_ligada,
  MIN(l_desligada.lamp_id) AS id_desligada,
  l_ligada.lamp_data AS ligada_em,
  MIN(l_desligada.lamp_data) AS desligada_em
FROM
  `lampadas_rel` AS l_ligada
LEFT JOIN
  lampadas_rel AS l_desligada
ON
  l_desligada.lamp_id > l_ligada.lamp_id AND l_desligada.lamp_estado = 0
WHERE
  l_ligada.lamp_estado = 1
GROUP BY
  l_ligada.lamp_id,
  l_ligada.lamp_data
ORDER BY
  l_ligada.lamp_id ASC

Dessa forma você poderia calcular a diferença com o método diff(http://php.net/manual/en/datetime.diff.php) da classe DateTime(http://php.net/manual/en/class.datetime.php) e formatá-lo posteriormente com o método format(http://php.net/manual/en/dateinterval.format.php) classe DateInterval(http://php.net/manual/en/class.dateinterval.php).

//http://php.net/manual/en/class.datetime.php
$ligada_em = new DateTime($row->ligada_em);
$desligada_em = new DateTime($row->desligada_em);

//http://php.net/manual/en/datetime.diff.php
$intervalo = $ligada_em->diff($desligada_em);

//http://php.net/manual/en/dateinterval.format.php
echo $intervalo->format('%D/%M/%Y %H:%I:%S');

Porem se você não deseja alterar a consulta, pode fazer o seguinte no PHP.

$sql = "SELECT * FROM lampadas_rel ORDER BY lamp_id ASC";

//...

$periodos = [];
$periodo = [];
while($row = $result->fetch_assoc()){
  if($row->lamp_estado) {
    $periodo['ligada_em'] = new DateTime($row->lamp_data);
  } else {
    $periodo['desligada_em'] = new DateTime($row->lamp_data);
    $periodo['intervalo'] = $periodo['ligada_em']->diff($periodo['desligada_em']);
    $periodos[] = $periodo;
    $periodo = [];
  }
}

if($periodo) {
  $periodo['desligada_em'] = new DateTime();
  $periodo['intervalo'] = $periodo['ligada_em']->diff($periodo['desligada_em']);
  $periodos[] = $periodo;
}

Dessa forma você irá ter um array com todos os períodos que lampada ficou acesa.

 

Não vou entrar em detalhes sobre como obter o tempo total, mas você pode conseguir utilizando o SUM no MySQL ou com algum "hack" utilizando dois objetos DateTime e o método add no PHP(https://stackoverflow.com/questions/11556731/how-we-can-add-two-date-intervals-in-php).

  • Gostei 1

Share this post


Link to post
Share on other sites
Em 02/04/2018 at 06:34, HwapX disse:

lamp_id é a chave primária da tabela ou identifica lampadas distintas e lamp_sec é uma sequencia incremental, ou ele agrupa o evento de ligar e desligar, ou identifica lampadas distintas?

 

Se for possível e do seu interesse publique o esquema da tabela lampadas_rel junto de alguns dados de exemplo, pois talvez você possa conseguir essa informação diretamente do banco, seja com uma consulta que calcule o tempo entre cada registro ou pré calculando via triggers.

Correto lamp_id identifica a lampada e lamp_sec é a sequencia do acionamento.  Estou usando lamp_sec não esta distinguido as lampadas a sequencia é por acionamento independente qual seja a lampada.

 

Minha tabela esta desta maneira.

lamp_sec guarda a seguencia de acionamento.

lamp_id que identifica qual a lampada acionada. 

lamp_data - marca horário que a lampada foi ligada ou desligada

lamp_estado - guarda o estado que ela estava ligada ou desligada

Share this post


Link to post
Share on other sites

Nesse caso basta ajustar as consultas e adicionar o lamp_Id ao group by.

SELECT
  l_ligada.lamp_id,
  l_ligada.lamp_sec AS ligada_sec,
  MIN(l_desligada.lamp_sec) AS desligada_sec,
  MIN(TIMEDIFF(IFNULL(l_desligada.lamp_data, CURRENT_TIMESTAMP), l_ligada.lamp_data)) as tempo_ligada
FROM
  `lampadas_rel` AS l_ligada
LEFT JOIN
  lampadas_rel AS l_desligada
ON
  l_desligada.lamp_id = l_ligada.lamp_id AND 
  l_desligada.lamp_estado = 0 AND
  l_desligada.lamp_sec > l_ligada.lamp_sec
WHERE
  l_ligada.lamp_estado = 1
GROUP BY
  l_ligada.lamp_sec,
  l_ligada.lamp_id
ORDER BY
  l_ligada.lamp_sec ASC
  
/*ou intervalo em segundos*/

SELECT
  l_ligada.lamp_id,
  l_ligada.lamp_sec AS ligada_sec,
  MIN(l_desligada.lamp_sec) AS desligada_sec,
  MIN(UNIX_TIMESTAMP(IFNULL(l_desligada.lamp_data, CURRENT_TIMESTAMP)) - UNIX_TIMESTAMP(l_ligada.lamp_data)) as tempo_ligada
FROM
  `lampadas_rel` AS l_ligada
LEFT JOIN
  lampadas_rel AS l_desligada
ON
  l_desligada.lamp_id = l_ligada.lamp_id AND 
  l_desligada.lamp_estado = 0 AND
  l_desligada.lamp_sec > l_ligada.lamp_sec
WHERE
  l_ligada.lamp_estado = 1
GROUP BY
  l_ligada.lamp_sec,
  l_ligada.lamp_id
ORDER BY
  l_ligada.lamp_sec ASC

/*Ou */

SELECT
  l_ligada.lamp_id,
  l_ligada.lamp_sec AS ligada_sec,
  MIN(l_desligada.lamp_sec) AS desligada_sec,
  SEC_TO_TIME(MIN(UNIX_TIMESTAMP(IFNULL(l_desligada.lamp_data, CURRENT_TIMESTAMP)) - UNIX_TIMESTAMP(l_ligada.lamp_data))) as tempo_ligada
FROM
  `lampadas_rel` AS l_ligada
LEFT JOIN
  lampadas_rel AS l_desligada
ON
  l_desligada.lamp_id = l_ligada.lamp_id AND 
  l_desligada.lamp_estado = 0 AND
  l_desligada.lamp_sec > l_ligada.lamp_sec
WHERE
  l_ligada.lamp_estado = 1
GROUP BY
  l_ligada.lamp_sec,
  l_ligada.lamp_id
ORDER BY
  l_ligada.lamp_sec ASC

A consulta acima pode ser testada em https://www.db-fiddle.com/f/8QeFNzPeGrN5ybhzQ5uPd1/0.

 

No PHP você teria que agrupar por lampada, fora isso o que disse anteriormente continua se aplicando.

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • By tatysouzac
      Minha view:
      <div>                            
                                          <form method="post" action="http://localhost/integradorcode/index.php/welcome/validar">
                                          EMAIL: <input type="text" name="email"  /> <br><br>
                                          SENHA:  <input type="password" name="senha"/> <br><br><br><br>
                                          <input class="myButton" type="submit" value="Entrar"/> <br><br>
                                          </form>
                                          <a href="Cadastro.php" class="myButton">Cadastrar</a><br><br>
                                          <a href="#" class="myButton">Esqueceu sua senha?</a>
               </div>
       
       
       
      Controller:
       
          public function validar(){
              //var_dump($_POST);
              $this->load->model("Cadastro_model");
              $result = $this->Cadastro_model->validar($_POST["email"],md5($_POST["senha"]));
              var_dump($result);
          }
       
       
      Model:
       
          function validar($email, $senha){
              return $this->db->query("SELECT * FROM `cadastro_clientes` WHERE email_cliente = '{$email}'  AND senha_cliente = '{$senha}' AND status = 1 LIMIT 1")->result_array();
          }
       
       
      Não da nenhuma mensagem de erro mas coloco senha e login certos do meu bd e o return não retorna nada array 0 
    • By terra
      Olá,
       Tenho esse codigo
       
      e gostaria de chamar  bairro = dados.address.suburb; aqui nesse função 
       
       
      Agradeço qualquer ajuda
    • By ricardonews
      olá pessoal, eu não estou conseguindo fazer o redirecionamento apos o cadastro para index, eu estou perdido entre os ifs e else, eu acho que só pode ser isso,  quando eu coloco meu código trava, e não faz nada. vou postar o print.

    • By Fábio Capello
      Oi pessoal tudo bem?sou novo no fórum estou desenvolvendo um sistema web preciso de ajuda meu dificuldade e para por segurança na páginas php.quando um usuário logado quer mudar de navegador ele cópia link e colou em outro navegador ele terá acesso mas quero que ele direcione para página de login 
    • By Dinho Nunes LC
      <div align="center" id="subtitulo"> Canais Abertos </div> <div class="ui cards"> <div class="card"> <div class="content"> <a href="globo.html" style="display: block; color: black"> <div align="center"> <div> <img class="ui tiny image" id="imagem_card_casa" src="assets/images/Rede_Globo_2014.png"> <div align="center" id = "nome_time_fora"> <b>Globo RJ</b> </div> </div> Onde "globo.html" seria substituído pelo link que esta em uma tabela do banco de dados.
       
      Já fiz a conexão. E tenho a base de dados pronta.
       
      Motivo pelo qual estou buscando ajuda:
       
      Faço manualmente a mudança de cada link (são mais de 300) diariamente para evitar copias de terceiros. Sendo assim poderia usar um CRUD para facilitar a troca dos links direto no banco de dados.
×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.