Trabalhando com datas em PHP

Nenhum produto encontrado nessa seleção.

Hoje vamos aprender a trabalhar com datas em PHP utilizando as funções date, mktime e time. Veremos como somar, subtrair, criar e utilizar as funções mencionadas. Além disso, também vamos ver as melhores práticas para salvar as datas em nosso banco de dados.

Pode parecer algo bastante simples, mas acredite, trabalhar com datas em qualquer linguagem de programação é algo bastante complexo, você precisa entender o funcionamento das funções e os formatos padrões de data para não fazer algo de maneira incorreta e ter que corrigir tudo depois.

Felizmente, o PHP nos deixa milhares de funções para facilitar a nossa vida em se tratando de datas, combinando certas funções você vai conseguir fazer qualquer coisa que precisar.

Antes de iniciar utilizando as funções, veja os melhores formatos para salvar datas no seu banco de dados ou trabalhar com os números.

Melhor formato para data no BD

Como nós somos Brasileiros, é natural utilizarmos o formato de data que estamos acostumados:

  • dd-mm-yyyy
  • dd-mm-yy
  • dd/mm/yyyy
  • dd/mm/yy

Por exemplo, hoje é dia dezenove de julho de dois mil e quatorze, escolhendo um dos formatos de data acima poderíamos utilizar 19/07/2014, não é?

O problema é que se utilizarmos este formato de data teremos milhares de erros:

  • Primeiro: não conseguimos somar;
  • Segundo: não conseguimos ordenar nosso banco de dados pela data;
  • Terceiro: este formato não é compatível praticamente nada, portanto não salve datas no formato DDMMYYYY (Dia, Mês e Ano).

Particularmente, gosto de utilizar timestamp para datas, ou seja, é o número da soma dos segundos desde 01/01/1970 até a data que você deseja, por exemplo, neste momento a data atual é 19/07/2014 09:13:57, em timestamp unix é 1405772037.

1405772037 é algo praticamente ilegível para nós, mas com o PHP eu faço o que quiser com este formato de data, posso utilizar a função date() e colocar a data no formato que mais me agradar de maneira simples.

Se você preferir, também pode utilizar o formato YYYY-MM-DD HH:MM:SS, também não existem problemas na utilização deste formato. A data que citei anteriormente seria 2014-07-19 09:13:57.

Com as horas você não precisa se preocupar, não precisa inverter nada, já que o formato é o mesmo que já conhecemos HH:MM:SS.

Observação: Lembre-se que estou falando em gravar a data no formato timestamp, para imprimir para o usuário você pode utilizar o formato que quiser. Você vai aprender a fazer isso mais adiante.

A função date() em PHP

O modo mais simples para pegar qualquer data e formatar os valores como preferir, é utilizando a função date().

date() retorna datas em PHP no formato que você quiser. É possível enviar um parâmetro com a data que deseja, ou pegar a data atual caso este parâmetro não seja enviado.

Se você for enviar o parâmetro com a data que deseja, a data deverá estar no formato timestamp unix (Você vai aprender a criar datas em timestamp mais adiante)

Observação: timestamp é opcional.

A função date() precisa de pelo menos um parâmetro para retornar o valor sem nenhum erro, o parâmetro obrigatório é o formato da data, veja os formatos disponíveis:

Caractere Descrição Valores retornados
Dia
d Dia do mês, 2 dígitos com preenchimento de zero 01 até 31
D Uma representação textual de um dia, três letras Mon até Sun
j Dia do mês sem preenchimento de zero 1 até 31
l ('L' minúsculo) A representação textual completa do dia da semana Sunday até Saturday
N Representação numérica ISO-8601 do dia da semana (adicionado no PHP 5.1.0) 1 (para Segunda) até 7 (para Domingo)
S Sufixo ordinal inglês para o dia do mês, 2 caracteres st, nd, rd ou th. Funciona bem com j
w Representação numérica do dia da semana 0 (para domingo) até 6 (para sábado)
z O dia do ano (começando do 0) 0 through 365
Semana
W Número do ano da semana ISO-8601, semanas começam na Segunda (adicionado no PHP 4.1.0) Exemplo: 42 (the 42nd week in the year)
Mês
F Um representação completa de um mês, como January ou March January até December
m Representação numérica de um mês, com leading zeros 01 a 12
M Uma representação textual curta de um mês, três letras Jan a Dec
n Representação numérica de um mês, sem leading zeros 1 a 12
t Número de dias de um dado mês 28 through 31
Ano
L Se está em um ano bissexto 1 se está em ano bissexto, 0 caso contrário.
o Número do ano ISO-8601. Este tem o mesmo valor como Y, exceto que se o número da semana ISO (W) pertence ao anterior ou próximo ano, o ano é usado ao invés. (adicionado no PHP 5.1.0) Exemplos: 1999 ou 2003
Y Uma representação de ano completa, 4 dígitos Exemplos: 1999 ou 2003
y Uma representação do ano com dois dígitos Exemplos: 99 ou 03
Tempo
a Antes/Depois de meio-dia em minúsculo am or pm
A Antes/Depois de meio-dia em maiúsculo AM or PM
B Swatch Internet time 000 até 999
g Formato 12-horas de uma hora sem preenchimento de zero 1 até 12
G Formato 24-horas de uma hora sem preenchimento de zero 0 até 23
h Formato 12-horas de uma hora com zero preenchendo à esquerda 01 até 12
H Formato 24-horas de uma hora com zero preenchendo à esquerda 00 até 23
i Minutos com zero preenchendo à esquerda 00 até 59
s Segundos, com zero preenchendo à esquerda 00 até 59
u Milisegundos (adicionado no PHP 5.2.2) Exemplo: 54321
Timezone
e Identificador de Timezone (adicionado no PHP 5.1.0) Exemplos: UTC, GMT, Atlantic/Azores
I (capital i) Se a data está ou não no horário de verão 1 se horário de verão, 0 caso contrário.
O Diferença para Greenwich time (GMT) em horas Exemplo: +0200
P Diferença para Greenwich time (GMT) com dois pontos entre horas e minutos (adicionado no PHP 5.1.3) Exemplo: +02:00
T Abreviação de Timezone Exemplos: EST, MDT
Z Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive. -43200 até 50400
Full Date/Time
c ISO 8601 date (adicionado no PHP 5) 2004-02-12T15:19:21+00:00
r » RFC 2822 formatted date Exemplo: Thu, 21 Dec 2000 16:01:07 +0200
U Segundos desde a Época Unix (January 1 1970 00:00:00 GMT) Veja também time()

Fonte: Manual do PHP;

Você pode utilizar os caracteres acima combinados com os caracteres para separação dos valores da sua data, por exemplo:

// Exemplo com barra (/)
echo date("d/m/Y");
// Mostra a data atual: 19/07/2014

// Exemplo com traço (-)
echo date("d-m-Y");
// Mostra a data atual: 19-07-2014

Você também pode criar uma variável com o valor retornado por date(), veja o exemplo:

$data = date("r");
echo $data;
// Mostra Sat, 19 Jul 2014 09:23:43 -0300

Também da para pegar uma data invertida (YYYY-MM-DD), ou no formato timestamp, para imprimir de outras maneiras, por exemplo:

Vamos pegar a data em que eu nasci em timestamp unix: 545913020.

$data = 545913020;

Agora vamos formatar no modo DD/MM/YY HH:MM:SS:

$data = 545913020;
echo date("d/m/Y H:i:s", $data);

Claro que eu não vou falar qual a data, veja se você aprendeu e me diga qual a data em que eu nasci .

A função mktime() em PHP

Agora que você aprendeu a formatar uma data, vamos aprender a criar um timestamp para utilizarmos com a função date().

A função mktime() é bem mais simples do que date(), mas ambas andam juntas, veja o formato:

echo mktime(date("H"), date("i"), date("s"), date("m"), date("d"), date("Y"));
// Mostra 1405772776 (data atual)

Ou seja, mktime precisa dos valores hora, minuto, segundo, mês, dia, ano, entre parênteses, para retornar um timestamp. A função date pode nos dar os valores separadamente, como mostrei anteriormente.

Eu imagino que você deva estar pensando o motivo para fazer isso, já que date() já retorna a data atual, por que você utilizaria as duas funções?

É bem simples, com mktime eu posso somar datas, ou criar timestamp de datas passadas, por exemplo, minha data de nascimento:

// mktime(hora, min., seg., mês, dia, ano);
$data = mktime(12,30,20,04,20,1987);

// Mostra 20-04-1987
echo date("d-m-Y", $data);

// Mostra 20/04/1987
echo date("d/m/Y", $data);

// Mostra 20-04-1987 12:30
echo date("d-m-Y H:i", $data);

// Mostra 1987 
echo date("Y", $data);

Agora vamos somar, para isso eu posso fazer date("m")+1, por exemplo, e estaria somando o mês atual mais um, ou ainda date("Y")+10 e estaria somando o ano atual mais 10.

Observação: Você pode somar as datas da maneira que quiser, por exemplo, dia, mês, ano, hora, minuto ou segundo, e o melhor da história, é que se a data passar, o PHP se encarrega de virar o dia, mês, etc. Veja um exemplo:

$data = mktime(date("H"), date("i"), date("s"), date("m")+20, date("d"), date("Y"));
echo date("d-m-Y", $data);

Isso deverá mostrar a data 19-03-2016 (a data da criação deste artigo mais 20 meses), por causa do date("m")+20.

Você também pode subtrair os valores se precisar.

A função time() em PHP

time() é a maneira mais simples para se obter um timestamp unix da data atual, simplesmente digite time() e terá o valor:

$data = time();
echo date("d-m-Y", $data);
// Mostra 19-07-2014

Você também pode somar time para obter outros valores:

$data = time() + (7 * 24 * 60 * 60);
// Data atual mais 7 dias, vezes 24 horas, vezes 60 mins, vezes 60segs.

echo date("d-m-Y", $data);
// Mostra 26-07-2014

Dicas adicionais

Em algum momento do seu script, você pode ter que dividir uma data, para isso você pode utilizar a função explode(), veja um exemplo:

<?php
// Data atual 19/07/2014
$data = date("d/m/Y");

// Explode a barra e retorna três arrays
$data = explode("/", $data);

// Cria três variáveis $dia $mes $ano
list($dia, $mes, $ano) = $data;

// Recria a data invertida
$data = "$ano/$mes/$dia";

// Mostra a data invertida
echo $data;

Ou você pode precisar criar um valor por mês de determinado cliente, por exemplo:

// Data atual 10/12/2011
$data = date("d/m/Y");

// Explode a barra e retorna três arrays
$data = explode("/", $data);

// Cria três variáveis $ano $mes $dia
list($dia, $mes, $ano) = $data;

// Recria a data invertida
$data = "$ano/$mes/$dia";

// Cria uma data final para os 12 meses posteriores
$data_final = date("Y/m/d",
mktime(
        date("H"),
        date("i"),
        date("s"),
        date("m")+12,
        date("d"),
        date("Y")
        )
);

// Faço o laço
while($data < $data_final)
{
    $data = date("Y/m/d",
        mktime(
            date("H"),
            date("i"),
            date("s"),
            $mes,
            $dia,
            $ano    
        )
    );
    $mes = $mes+1;
    echo $data . "rn";
}

Isso irá imprimir:

2014/07/19
2014/08/19
2014/09/19
2014/10/19
2014/11/19
2014/12/19
2015/01/19
2015/02/19
2015/03/19
2015/04/19
2015/05/19
2015/06/19
2015/07/19

Existem maneiras mais fáceis de fazer isso, mas quis mostrar apenas as funções que a gente já mostrou em aulas anteriores.

Aulas anteriores

Por falar em aulas anteriores, não deixe de conferir nosso curso de PHP gratuito.