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 rogerblower
      o Google me avisou de dois erros no meu site;
       
      Clickable elements too close together
      Text too small to read
       
      Na verificação constatei que o erro é;
       
      Fatal error:  Call to undefined function db_connect() in
       
      O php não me mostra esse erro mesmo habilitando os erros no php ini os arquivos de conexão que estou usando são;
       
      ini.php
      <?php define('DB_HOST', 'localhost'); define('DB_USER', 'user'); define('DB_PASS', 'senha'); define('DB_NAME', 'banco'); ini_set('display_errors', true); error_reporting(E_ALL); require_once 'functions.php'; functions.php
       
      <?php function db_connect() { $pdo = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8', DB_USER, DB_PASS); return $pdo; } function make_hash($str) { return sha1(md5($str)); } function isLoggedIn() { if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in']!== true) { return false; } return true; } O erro esta nesta linha
      <?php $pdo = db_connect(); $sql = $pdo->prepare("SELECT * FROM servicos "); $sql->execute(); while($row=$sql->fetch(PDO::FETCH_ASSOC)){ echo'<a href="servicos.php?id='.$row['id'].'">'.$row['servico'].'</a>'; } Incluo a conexão com banco na header.php e nas demais páginas não aparece o erro
      realmente não sei o que pode estar acontecendo.
      se alguém pode me ajudar?
       
      Obrigado
       
    • By violin101
      Caros amigos, saudações...
       
      Por favor, me perdoa em recorrer ao auxílio dos amigos.
       
      Tenho os seguintes CAMPOS no Mysql:
      ===[ id_movimento
      ===[ dta_movimento
      ===[ num_movimento
      ===[ status_movimento
       
      Minha dúvida é o seguinte:
      ==> como faço para no campo num_movimento após o insert no banco de dados, o sistema possa garvar da seguinte forma:
      ========[ pega o ID do movimento = 1
      ========[ pega uma String como:  E = entrada | S = saída | D = devolução
      ========[ grava no campo num_movimento desta forma: E-00001
       
      Na MODEL capturo o último ID desta forma:
      //Pega o Último ID public function lastID(){ return $this->db->insert_id(); }  
      Na CONTROLLER trago a informação do último ID desta forma:
      $ultimoID = $this->movimentos_model->lastID();  
      Grato a todos.
       
      Cesar
    • By nazesaria
      Ola, gostaria de saber se tem alguma forma de eu baixar essas paginas completa em .php, se eu clico nela vai em uma pagina em branco.
      E acessando direto do site não teria como, gostaria de ser por esse metedo, é possível? Como?
    • By R4gn3ls0n
      Ao hospedar um arquivo no phpMyAdmin apareceu esse erro, como posso resolver?
      Linhas:
      -- version 4.3.8
      -- http://www.phpmyadmin.net
      --
      -- Host: localhost:3306
      -- Tempo de geração: 28/02/2018 às 19:49
      -- Versão do servidor: 5.6.32-78.1
      -- Versão do PHP: 5.6.30
       
      ______________________________
       
      SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
      SET time_zone = "+00:00";
       

    • By helkton
      galera minha duvida é a seguinte....
      faço a seguinte busca e monto um pdf pra um certificado, e neste certificado preciso coletar todas as materias referente ao curso do mesmo
      $sqlConteudoCurso = "SELECT * FROM conteudo_curso where idCursoConteudo = '$idCurso' order by idConteudo ASC; $conectaConteudoCurso = $conecta->query($sqlConteudoCurso); //conteudoCurso $pdf->SetFont('Arial', '', 11); // Tipo de fonte e tamanhos $pdf->SetTextColor(10,15,35); $pdf->SetXY(10,75); //Parte chata onde tem que ficar ajustando a posição X e Y while($resultConteudoCurso = $conectaConteudoCurso->fetch_object()){ $conteudoCurso = $resultConteudoCurso->nomeConteudo; $pdf->MultiCell(75, 5, $conteudoCurso,'0', 'L', 0);// Tamanho width e height e posição } ok esta é a consulta que realizo no banco de dados ele me retorna a materia referente ao curso certinho, digamos que o curso tenha umas 20 matérias, ele vai imprimir certinho conforme as configurações de espaçamentos...
      AGORA O B.O é seguinte quando o curso acontece de ter tipo umas umas 40 MATÉRIAS ele acaba gerando outra página de pdf
      o que eu queria era que não gerasse outra pagina e sim partisse para o lado direito, pois é um certificado
      TIPO ASSIM....
      MATERIA 1 DO CURSO 1 MATERIA 11 DO CURSO 1 MATERIA 2 DO CURSO 1 MATERIA 12 DO CURSO 1 MATERIA 3 DO CURSO 1 MATERIA 13 DO CURSO 1 MATERIA 4 DO CURSO 1 MATERIA 14 DO CURSO 1 MATERIA 5 DO CURSO 1 MATERIA 15 DO CURSO 1 MATERIA 6 DO CURSO 1 MATERIA 16 DO CURSO 1 MATERIA 7 DO CURSO 1 MATERIA 17 DO CURSO 1 MATERIA 8 DO CURSO 1 MATERIA 18 DO CURSO 1 MATERIA 9 DO CURSO 1 MATERIA 19 DO CURSO 1 MATERIA 10 DO CURSO 1 MATERIA 20 DO CURSO 1  
×

Important Information

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