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

Postado por Luiz Otávio em 10/12/2011 às 19:29:57 na categoria Webmaster

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 . "rn";
 } 

 

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:

Mais sobre: Trabalhando Data PHP date() mktime() time()

Mais sobre "Webmaster"

Ver tudo sobre "Webmaster"

Comentários

Deixe a sua opinião, recado ou dúvida abaixo:

Comentar usando o facebook

@luiz_scout (Luiz Felipe) disse:

Em 11/12/2011 às 00:51:00

O autor está de parabéns pelo curso, começou com o basicão e agora está ensinando o essencial para quem quer aprender php. Gostaria de saber o total de aulas, para poder montar uma apostila impressa e estudar com calma. Essa já é a ultima aula?

Responder para Luiz Felipe | Denunciar

@todoespaco (Luiz Otávio) respondeu:

Em 11/12/2011 às 02:55:35

Amigo, creio que as aulas nunca deverão parar. Sempre teremos um script aqui, outro ali, uma função e coisas do tipo.

Ainda tem muito chão para explicar :)

Responder para Luiz Felipe | Denunciar

Kaleo_rs disse:

Em 11/12/2011 às 11:03:00

Parabéns pela ótima qualidade e pela forma simples de postar o assunto... Tá ficando ótimo...

Responder para Kaleo_rs | Denunciar

Hugo disse:

Em 10/03/2012 às 11:54:45

Excelente conteúdo, parabéns!

Responder para Hugo | Denunciar

José Augusto disse:

Em 03/07/2012 às 22:22:20

Como usar o date() e inserir o "às" antes das horas? Igual acontece aqui nos comentários: "Em 10/03/2012 às 11:54:45".
Obrigado.

Responder para José Augusto | Denunciar

@todoespaco (Luiz Otávio) respondeu:

Em 04/07/2012 às 07:52:40

echo date('d/m/Y') . ' às ' . date('H:i:s');

Responder para José Augusto | Denunciar

José Augusto respondeu:

Em 04/07/2012 às 10:19:39

Obrigado pela resposta e parabéns pelo curso.

Responder para José Augusto | Denunciar

Bruno Castro disse:

Em 28/07/2012 às 14:13:51

como fazemos para a data pegar o ultimo dia do mes quando nao tiver a data inicial da expressao. exemplo: data inicial 31/08/2012 o proximo mes nao tem 31 entao ele gera 01/10/2012 e queria que ficasse assim 30/09/2012. usando essa função ele fica assim:
31/08/2012
01/10/2012
31/10/2012
01/12/2012
31/12/2012
31/01/2013
03/03/2013
31/03/2013
01/05/2013
31/05/2013
01/07/2013
31/07/2013

Responder para Bruno Castro | Denunciar

@todoespaco (Luiz Otávio) respondeu:

Em 29/07/2012 às 07:38:19

Olha não testei, mas veja se isso resolve:

<?php
function getLastDay($m = false)
{
if( !empty( $m ) )
{
$date = mktime( 0, 0, 0, $m, 0, date('Y') );
}
else
{
$date = mktime( 0, 0, 0, date('m'), 0, date('Y') );
}
return date('d/m/Y', $date);
}

echo getLastDay(02);
?>

Responder para Bruno Castro | Denunciar

Ângelo Castro disse:

Em 03/12/2012 às 20:58:51

Parabéns pelo curso de PHP. Tenho encontrado aqui excelentes dicas. Tenho um blog em wordpress chamado Cliente em Foco (clienteemfoco.com)e lá formatei a data como "j \d\e F \d\e Y". Gostaria de saber o que fazer para o nome do mês ficar com a primeira letra também minúscula. Abraço a todos.

Responder para Ângelo Castro | Denunciar

Matheus disse:

Em 10/12/2012 às 16:35:21

Queria saber se há alguma diferença entre time() e date("U")...

Acho que não, mas só pra saber mesmo....
Obrigado!

Responder para Matheus | Denunciar

Comentar usando o TEO

Nome *:
Email *:
Twitter (@nomedoseuusuario):
Quanto é *?
Comentário *:
Campos Obrigatórios *

siga o teo »

Feed / RSS Todo Espaço Online no Twitter Todo Espaço Online no Facebook Todo Espaço Online no Google+

receba no email »

compartilhe »

mais recente »

mais lidas »

linkerama »

facebook »

parceiros »

Copyright © 2011 todoespacoonline.com ®. Todos os direitos reservados.