Trabalhando com datas em PHP - date(), mktime(), time()

Continuando com nosso pequeno curso de PHP, hoje vamos aprender a trabalhar com datas utilizando as funções date(), mktime() e time(). Vamos aprender a somar, subtrair, criar e utilizar as funções, 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 para não fazer algo de maneira incorreta e ter que ficar corrigindo 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

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 dez de dezembro de dois mil e onze, escolhendo um dos formatos de data acima poderíamos utilizar 10/12/2011, não é?

O problema é que se utilizarmos este formato de data teremos milhares de erros, primeiro é que não conseguimos somar, segundo  é que 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.

Particularmente, gosto de utilizar timestamp para datas, ou seja, é o número da soma dos segundos de 01/01/1970 até a data que você deseja, por exemplo, neste momento a data atual é 10/12/2011 20:02:36, em timestamp unix é 1323543756.

1323543756 é algo praticamente ilegível para nós, mas com o PHP eu faço praticamente 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, também não existem problemas na utilização deste formato. A data que citei anteriormente seria 2011-12-10 20:02:36.

Com as horas você não precisa se preocupar, não precisa inverter, 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.

date()

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

Esta função retorna uma string de acordo com o formato dado usando timestamp ou a hora atual local se você não passar o argumento timestamp.

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 digitos 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 divisão dos valores da sua data, por exemplo:

// Exemplo com barra (/)
echo date("d/m/Y");
// Mostra 10/12/2011 (A data atual)

// Exemplo com traço (-)
echo date("d-m-Y");
// Mostra 10-12-2011 (A data atual)

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

$data = date("r");
echo $data;
// Mostra Sat, 10 Dec 2011 21:04:02 +0100

Também da para pegar uma data invertida ou no formato timestamp e 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 smiley.

mktime()

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:

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

Ou seja, mktime precisa dos valores hora, minuto, segundo, mês, dia, ano entre parênteses para retornar um timestamp e 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 o 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 10-08-2013 (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.

time()

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 10-12-2011

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

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

echo date("d-m-Y", $data);
// Mostra 17-12-2011

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:

// 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 $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 . "\r\n";
}

Isso irá imprimir:

2011/12/10
2012/01/10
2012/02/10
2012/03/10
2012/04/10
2012/05/10
2012/06/10
2012/07/10
2012/08/10
2012/09/10
2012/10/10
2012/11/10
2012/12/10

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

Aulas anteriores

Veja o que você já aprendeu aqui no TEO:

Tags: Trabalhando Data PHP date() mktime() time()


Comentários