Como manipular, pegar e formatar datas e horários em PHP: data atual, hora, comparação e formatação

Trabalhar com datas e horários é uma necessidade constante para quem desenvolve em PHP. Seja para exibir a data atual em PHP, formatar horário, calcular intervalos ou comparar datas em PHP, este artigo mostra como fazer tudo isso de maneira prática e segura.
Suponha a necessidade de desenvolver um sistema de controle de ponto para uso na web, demandando o registro preciso de datas e horários.
Como aproximadamente 80% da web utiliza PHP, essa linguagem se apresenta como uma excelente opção para implementar esse tipo de solução.
Esse sistema deve ser capaz de exibir a data e hora de cada marcação (entrada e saída) das pessoas colaboradoras, além de calcular o intervalo de horas trabalhadas em cada dia.
Além disso, é essencial saber como pegar a data de hoje em PHP, exibir a hora, entender como funciona a função date em PHP e lidar com diferentes formatações de datas e fusos horários.
Como usar a função date em PHP para pegar a data e hora atual
A função date é amplamente utilizada em PHP para obter a data atual e permite definir facilmente o formato desejado.
Em muitos sistemas, precisamos obter a data atual em PHP (‘data de hoje PHP’) de forma simples e clara. Veja abaixo um exemplo de como usar a função date para isso:
PHP
<?php
$hoje = date('d/m/Y');
echo $hoje;Este código exibirá: 20/03/2019.
Como você já deve ter suposto, o d representa o dia, m representa o mês enquanto Y representa o ano com 4 dígitos. Se quiséssemos o ano apenas com 2 dígitos (19 no nosso exemplo), bastaria utilizar y (em minúsculo).
Com esta mesma função podemos também pegar o horário atual, além da data. Continua bem fácil:
PHP
<?php
$agora = date('d/m/Y H:i');
echo $agora;E a saída será: 20/03/2019 16:58
Observe que, enquanto m representa o mês, i representa os minutos. Para saber mais sobre cada caractere de formatação disponível, consulte a documentação da função.
Como comparar datas em PHP: diferença entre duas datas
Já conseguimos obter as datas (retornadas como string). Agora, vamos analisar como calcular o intervalo entre elas para exibir as horas trabalhadas.
Na documentação PHP, a função `date_diff é apresentada como solução para calcular intervalos, porém requer como parâmetros objetos que implementam a interface DateTimeInterface`, e não strings.
Embora tenhamos utilizado até este ponto a função date, existem alternativas orientadas a objetos, como a classe DateTime, que implementa a interface DateTimeInterface. Com essa classe é possível obter facilmente datas e horários de forma mais flexível.
O código que tínhamos antes não muda muito. Veja como fica utilizando a classe que acabamos de conhecer:
PHP
<?php
$agora = new DateTime(); // Pega o momento atual
echo $agora->format('d/m/Y H:i'); // Exibe no formato desejadoSe nenhum parâmetro for passado para o construtor de DateTime, o momento atual será utilizado. Também é possível passar uma string representando um momento específico, como nos exemplos a seguir:
PHP
<?php
$agora = new DateTime('now');
$ontem = new DateTime('yesterday');
$dia15 = new DateTime('2019-03-15');Caso seja necessário criar um objeto DateTime a partir de uma string em outro formato, utilize o método createFromFormat, como demonstrado abaixo:
PHP
<?php
$formato = 'd/m/Y';
$stringDataDia15 = '15/03/2019';
$dia15 = DateTime::createFromFormat($formato, $stringDataDia15);Como calcular diferença entre datas e horários em PHP (DateTime e diff)
Trabalhar com a classe DateTime em PHP é importante para realizar contas precisas, saber como calcular a diferença entre datas (comparar datas em PHP), além de permitir fácil manipulação do formato de datas e horários.
A interface DateTimeInterface expõe um método chamado diff, que recebe um outro objeto deste mesmo tipo como parâmetro, ou seja, podemos chamar a partir de nosso objeto de datas, o método diff passando uma outra data como parâmetro. Vamos ver como ficaria isso:
PHP
<?php
$entrada = new DateTime('09:00');
$saida = new DateTime('18:00');
$intervalo = $saida->diff($entrada);
print_r($intervalo);E com isso temos a seguinte saída:
PHP
DateInterval Object
(
[y] => 0
[m] => 0
[d] => 0
[h] => 9
[i] => 0
[s] => 0
[f] => 0
[weekday] => 0
[weekday_behavior] => 0
[first_last_day_of] => 0
[invert] => 1
[days] => 0
[special_type] => 0
[special_amount] => 0
[have_weekday_relative] => 0
[have_special_relative] => 0
)Ao criar os objetos de data e hora, apenas os horários foram informados, sem especificar os dias. Nesse caso, o PHP utiliza a data atual junto ao horário informado.
O retorno do método diff é um objeto do tipo DateInterval. Esse objeto fornece a quantidade de anos, meses, dias, horas, minutos e segundos entre duas datas. No exemplo apresentado, temos 9 horas de intervalo, que podem ser exibidas assim:
PHP
// ...
echo $interval->h; // h = horasPS.: Caso você tenha analisado a saída do print_r, viu que há as propriedades d e days.
Num intervalo de exatamente um ano, a propriedade y teria o valor de 1, enquanto a propriedade d teria o valor zerado, o que significa que há 1 ano e 0 dias de diferença. A propriedade days teria 365 (ou 364, dependendo das datas exatas) como seu valor, indicando o número total de dias
Como lidar com fuso horário em PHP ao pegar a data e hora atual
Durante a implantação do sistema em diferentes servidores, pode-se perceber que diferença de fusos horários entre as máquinas pode ocasionar inconsistências nos registros de ponto.
Para evitar que o fuso horário de cada máquina impacte negativamente no funcionamento do sistema, recomenda-se definir explicitamente o fuso horário no código.
Em PHP, essa configuração é simples. Ao criar o objeto de data, basta informar o fuso horário desejado como parâmetro. Veja como realizar essa configuração:
PHP
<?php
$timezone = new DateTimeZone('America/Sao_Paulo');
$agora = new DateTime('now', $timezone);Repare que nós colocamos o timezone como America/Sao_Paulo. Mas e se quisermos saber outras possibilidades? É possível ver a lista de fusos horários suportados pelo DateTimeZone com o método DateTimeZone::listIdentifiers():
PHP
<?php
print_r(DateTimeZone::listIdentifiers());Além disso, entender e definir corretamente o fuso horário é fundamental para que ao usar funções como date() ou DateTime, você obtenha a data e hora corretas, o que evita erros típicos ao pegar a data atual em PHP.
Trabalhar com datas e fusos horários com PHP é moleza!
Como usar DateTimeImmutable para manipular datas em PHP sem alterar o objeto original
Conseguimos chegar na implementação desejada. Conseguimos pegar as datas que queremos (utilizando Orientação a Objetos, inclusive), calcular a diferença entre elas e até trabalhar com diferentes fusos horários.
Além disso, existe outra classe que implementa a interface DateTimeInterface: a DateTimeImmutable.
A classe DateTimeImmutable! Ela pode ser utilizada da mesma forma que a classe DateTime, mas as operações que ela expõe retornam uma nova data, e não alteram a original. Pareceu confuso?
Vamos ver, na prática, a diferença entre essas classes e como realizar algumas operações adicionais com datas:
PHP
<?php
$umDia = new DateInterval('P1D'); // Intervalo de 1 dia
// Com DateTime:
$hoje = new DateTime();
echo $hoje->format('d/m'); // Saída 20/03
$hoje->add($umDia); // Altera o valor de $hoje
echo $hoje->format('d/m'); // Saída 21/03
// Com DateTimeImmutable
$hoje = new DateTimeImmutable();
echo $hoje->format('d/m'); // Saída 20/03
$amanha = $hoje->add($umDia); // Não altera o valor de $hoje
echo $hoje->format('d/m'); // Saída 20/03
echo $amanha->format('d/m'); // Saída 21/03Note que, ao adicionar um intervalo de um dia ao objeto DateTime (com o método add), o próprio objeto é alterado. Porém, ao utilizar DateTimeImmutable, o valor original é mantido e é retornado um novo objeto com a alteração.
Boas práticas atuais: A comunidade PHP recomenda preferir DateTimeImmutable sobre DateTime na maioria dos casos, pois a imutabilidade previne bugs difíceis de rastrear causados por modificações acidentais de objetos de data compartilhados entre diferentes partes do código.
Se ficou curioso sobre como criar um intervalo pode dar uma olhada na documentação. Mas basicamente, P significa um período, e adicionamos 1D, que quer dizer um dia.
Se quiséssemos adicionar 2 dias e 3 horas, ficaria: P2DT3H, onde o T indica que as informações a seguir são sobre o horário (hora, minuto ou segundo).
Resumo: melhores práticas para pegar, comparar e formatar datas e horários em PHP
Neste artigo, partimos de uma necessidade prática de manipulação de datas em PHP e demonstramos que a linguagem possui uma API nativa robusta para criação de datas, manipulação, cálculos de intervalos e configuração de fusos horários, sem a necessidade de bibliotecas externas.
Aprofunde seu conhecimento sobre como trabalhar com data e hora em PHP (inclusive como pegar o dia da semana em PHP, formatar data, e tratamentos avançados com DateTime e DateInterval) acessando os cursos da formação PHP da Alura!




