Ir para conteúdo

POWERED BY:

Arquivado

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

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;

 

Compartilhar este post


Link para o post
Compartilhar em outros 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.

Compartilhar este post


Link para o post
Compartilhar em outros 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).

Compartilhar este post


Link para o post
Compartilhar em outros 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

Compartilhar este post


Link para o post
Compartilhar em outros 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.

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por violin101
      Caros amigos do grupo, saudações e um feliz 2025.
       
      Estou com uma pequena dúvida referente a Teclas de Atalho.

      Quando o Caps Lock está ativado o Comando da Tecla de Atalho não funciona.
      ou seja:
      se estiver para letra minúscula ====> funciona
      se estiver para letra maiúscula ====> não funciona
       
      Como consigo evitar essa falha, tanto para Letra Maiúscula quanto Minúscula ?

      o Código está assim:
      document.addEventListener( 'keydown', evt => { if (!evt.ctrlKey || evt.key !== 'r' ) return;// Não é Ctrl+r, portanto interrompemos o script evt.preventDefault(); });  
      Grato,
       
      Cesar
    • Por violin101
      Caros amigos, saudações.
       
      Por favor, poderiam me ajudar.

      Estou com a seguinte dúvida:
      --> como faço para para implementar o input código do produto, para quando o usuário digitar o ID o sistema espera de 1s a 2s, sem ter que pressionar a tecla ENTER.

      exemplo:
      código   ----   descrição
           1       -----   produto_A
       
      Grato,
       
      Cesar
    • Por violin101
      Caros amigos, saudações.
       
      Humildemente peço desculpa por postar uma dúvida que tenho.

      Preciso salvar no MySql, os seguinte Registro:

      1 - Principal
      ====> minha dúvida começa aqui
      ==========> como faço para o Sistema Contar Automaticamente o que estiver despois do 1.____?
      1.01 - Matriz
      1.01.0001 - Estoque
      1.01.0002 - Oficina
      etc

      2 - Secundário
      2.01 - Loja_1
      2.01.0001 - Caixa
      2.01.0002 - Recepção
      etc
       
      Resumindo seria como se fosse um Cadastro de PLANO de CONTAS CONTÁBEIL.

      Grato,


      Cesar









       
    • Por violin101
      Caros amigos, saudações.

      Por favor, me perdoa em recorrer a orientação dos amigos.

      Preciso fazer um Relatório onde o usuário pode Gerar uma Lista com prazo para vencimento de: 15 / 20/ 30 dias da data atual.

      Tem como montar uma SQL para o sistema fazer uma busca no MySql por período ou dias próximo ao vencimento ?

      Tentei fazer assim, mas o SQL me traz tudo:
      $query = "SELECT faturamento.*, DATE_ADD(faturamento.dataVencimento, INTERVAL 30 DAY), fornecedor.* FROM faturamento INNER JOIN fornecedor ON fornecedor.idfornecedor = faturamento.id_fornecedor WHERE faturamento.statusFatur = 1 ORDER BY faturamento.idFaturamento $ordenar ";  
      Grato,
       
      Cesar
       
       
       
       
    • Por violin101
      Caros amigos, saudações
       
      Por favor, me perdoa em recorrer a orientação dos amigos, tenho uma dúvida.
       
      Gostaria de uma rotina onde o Sistema possa acusar para o usuário antes dos 30 dias, grifar na Tabela o aviso de vencimento próximo, por exemplo:
       
      Data Atual: 15/11/2024
                                           Vencimento
      Fornecedor.....................Data.....................Valor
      Fornecedor_1...........01/12/2024..........R$ 120,00 <== grifar a linha de Laranja
      Fornecedor_1...........01/01/2025..........R$ 130,00
      Fornecedor_2...........15/12/2024..........R$ 200,00 <== grifar a linha de Amarelo
      Fornecedor_2...........15/01/2025..........R$ 230,00
      Fornecedor_3...........20/12/2024..........R$ 150,00
       
      Alguém tem alguma dica ou leitura sobre este assunto ?

      Grato,
       
      Cesar
×

Informação importante

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