PHP: Datas e Horas Programação de Servidores Marx Gomes Van der Linden Datas e Horas O uso e manipulação de datas e horas é importante em quase todos os aspectos que envolvem programação para web: Organizar dados cronologicamente Agendar eventos Verificar a última vez que um usuário se conectou Lidar com informações como data de envio e recebimento de um produto em uma loja virtual 2 Expiração de http://marx.vanderlinden.com.br/ cookies Datas e Horas Ao contrário de dados simples como strings e números, uma data/hora pode ser composta de um conjunto de informações variável e potencialmente grande: Hora Minuto Segundo Dia do Mês Dia da Semana Mês http://marx.vanderlinden.com.br/ Ano 3 Datas e Horas Cálculos com datas e horas também não são triviais. Horas, minutos e segundos variam de 0 a 59. O número de dias em um mês é variável. Quanto é 12h50min + 843min? Quantos segundos se passaram desde 18/05/2005, 8h45? http://marx.vanderlinden.com.br/ 4 Timestamp Unix Sistemas baseados em Unix, como o Linux, utilizam um mecanismo padronizado para se contar o tempo. Um instante de tempo em Unix é armazena-se um número inteiro (positivo ou negativo) chamado timestamp. Tipicamente, o timestamp é armazenado em 4 bytes (32 bits). Este também é o sistema adotado por PHP, independentemente da plataforma. http://marx.vanderlinden.com.br/ 5 A Época Unix O timestamp Unix correspondente ao número de segundos passados desde o início da Época Unix ou Era Unix (Epoch). 00:00:00, 1 de Janeiro de 1970 (UTC) UTC → Zona temporal precisamente definida, aproximadamente equivalente a GMT (Greenwich). http://marx.vanderlinden.com.br/ 6 time() A função time retorna o número de segundos passados desde a época (timestamp atual). echo time(); 1221689189 http://marx.vanderlinden.com.br/ 7 strftime A função strftime converte um inteiro em uma data legível. Sintaxe: strftime($formato, [$tempo]) Se $tempo for omitido, é utilizado o momento atual (time()) http://marx.vanderlinden.com.br/ 8 Formato (strftime) %a - Nome da semana abreviado %A - Nome da semana completo %b - Nome do mês abreviado %B - Nome do mês completo %c - Representação da data e hora preferida %d - Dia do mês como um número decimal (de 01 até 31) %y - Ano com 2 dígitos %Y - Ano com 4http://marx.vanderlinden.com.br/ dígitos 9 Formato (strftime) %H - Hora como um número decimal usando um relógio de 24-horas (de 00 até 23) %I - Hora como um número decimal usando um relógio de 12-horas (de 01 até 12) %m - Mês como número decimal (de 01 até 12) %M - Minuto como número decimal %r - Hora em notação a.m. e p.m. %R - Hora em notação de 24 horas %S - Segundo como um número decimal %T - Hora corrente, igual a %H:%M:%S http://marx.vanderlinden.com.br/ 10 strftime echo strftime("%c<br>\n") ; echo strftime( "Hoje é %A, dia %d de %B de %G.<br>\n" ); echo strftime("São %Hh%M (%T)<br>\n"); Wed Sep 17 22:32:04 2008<br> Hoje é Wednesday, dia 17 de September de 2008.<br> São 22h32 (22:32:04)<br> http://marx.vanderlinden.com.br/ 11 setlocale A função setlocale orienta o PHP a usar configurações locais para a formatação de vários tipos de dados, entre eles os de data e hora. Cada localização está associada a uma string, cujo formato depende do sistema operacional. O sucesso da função depende de configurações do sistema operacional. http://marx.vanderlinden.com.br/ 12 setlocale Sintaxe: setlocale(TIPO, $locale1, [$locale2], [locale3]...) TIPO é uma constante que define que tipo localização será afetada (para data e hora, LC_TIME) Podem-se especificar várias localizações, que serão tentadas em ordem de prioridade http://marx.vanderlinden.com.br/ 13 setlocale setlocale(LC_TIME, 'pt_BR'); echo strftime("%c<br>\n") ; echo strftime( "Hoje é %A, dia %d de %B de %G.<br>\n" ); echo strftime("São %Hh%M (%T)<br>\n"); Qua 17 Set 2008 22:41:46 BRT<br> Hoje é quarta, dia 17 de setembro de 2008.<br> São 22h41 (22:41:46)<br> http://marx.vanderlinden.com.br/ 14 $eventos = array( "Pré-história" => (-pow(2,32)/2), "Início da época" => 0, "Festa" => 1000000000, "Próxima festa" => 2000000000, "Fim dos tempos" => (pow(2,32)/2-1) ); setlocale(LC_TIME, 'pt_BR'); echo "<table><tr> <th>Evento</th> <th>Data</th> <th>Tempo Unix</th> </tr>\n"; foreach($eventos as $evento => $data){ echo strftime("<tr> <td>$evento</td> <td>%d/%b/%Y, %T</td> <td>$data</td> </tr>\n", $data); } 15 echo "</table>"; http://marx.vanderlinden.com.br/ Datas Importantes http://marx.vanderlinden.com.br/ 16 getdate A função getdate retorna as informações de um timestamp como um array associativo. Sintaxe: getdate([$timestamp]) Se omitido, é usado o timestamp do momento atual. http://marx.vanderlinden.com.br/ 17 getdate Campos do array retornado: "seconds" Segundos "minutes" Minutos "hours" Horas "mday" Dia do mês "wday" Dia da semana (número) "mon" Mês (número) "year" Ano "yday" Dia do ano "weekday" Dia da semana (nome) "month" http://marx.vanderlinden.com.br/ Mês (nome) 18 getdate $ts = mktime(12,30,12, 3,19,2005); $data = getdate($ts); echo "$data[hours] horas e $data[minutes] minutos, ano $data[year]."; 12 horas e 30 minutos, ano 2005. http://marx.vanderlinden.com.br/ 19 mktime A função mktime faz o reverso de strftime e getdate, isto é, construi um timestamp baseado em informações fornecidas de data e hora. Sintaxe: mktime ([$hora], [$minuto], [$segundo] [$mês], [$dia], [$ano]) Os argumentos não fornecidos são definidos para o valor da data/hora atual. http://marx.vanderlinden.com.br/ 20 mktime $ts = mktime(12,30,12, 3,18,2010); echo strftime("O timestamp $ts equivale a %d/%b/%Y, %T", $ts); O timestamp 1268926212 equivale a 18/Mar/2010, 12:30:12 http://marx.vanderlinden.com.br/ 21 Manipulando o timestamp Sabendo que o timestamp é simplesmente um número inteiro medido em segundos, é possível manipulá-lo diretamente. http://marx.vanderlinden.com.br/ 22 Manipulando o timestamp $a = mktime(12,30,12, 3,19,2005); $b = $a + 60*60; // + 1 hora $c = $b + 60*60*24; // + 1 dia foreach( array($a,$b,$c) as $t) echo strftime("%d/%b/%Y, %T<br>\n", $t); 19/Mar/2005, 12:30:12<br> 19/Mar/2005, 13:30:12<br> 20/Mar/2005, 13:30:12<br> http://marx.vanderlinden.com.br/ 23 strtotime A função strtotime fornece uma maneira mais fácil e poderosa de se executarem operações de adição e subtração em timestamps. Sintaxe: strtotime($frase, [$referência]) $frase é uma expressão em inglês padronizada $referência é o timestamp ao qual será adicionado ou subtraído o tempo http://marx.vanderlinden.com.br/ 24 Sintaxe da Frase A frase usada no primeiro parâmetro de strtotime pode ser do tipo: + ou - seguido do tempo a ser modificado: "+1 day" "-3 days" "+1 week 2 days 4 hours 2 seconds" next ou last seguido de um dia da semana: "next Thursday" "last Monday" http://marx.vanderlinden.com.br/ 25 Sintaxe da Frase Não altera a data "now" → Usado sem o segundo argumento Data absoluta: "10 September 2000" http://marx.vanderlinden.com.br/ 26 Exemplo $a = $b = $c = $b); $d = $e = mktime(12,30,12, 3,19,2005); strtotime("+1 day", $a); strtotime("+2 weeks 8 hour 20 minutes", strtotime("next Thursday", $c); strtotime("last Saturday", $d); foreach( array($a,$b,$c,$d,$e) as $t) echo strftime("%d/%b/%Y, %T<br>\n", $t); 19/Mar/2005, 20/Mar/2005, 03/Apr/2005, 07/Apr/2005, 02/Apr/2005, 12:30:12<br> 12:30:12<br> 20:50:12<br> 00:00:00<br> http://marx.vanderlinden.com.br/ 00:00:00<br> 27