Back-End

18 mai, 2018

Manipulando datas em PHP com Carbon

Publicidade

Uma pergunta que frequentemente vejo no fórum do iMasters, outros fóruns de desenvolvimento, redes sociais ou no Stack Overflow em relação a um tema não tão avançado em PHP, é sobre formatação de datas.

Ainda hoje, muitos desenvolvedores PHP só conhecem as funções date(), time() ou strtotime() e depois fazem um monte de contas matemáticas estranhas para retornar o valor dos dias, da data atual, fazer soma ou diminuição de datas e comparação (o que é bem esquisito fazer com esse tipo de retorno).

Bem, no PHP já temos a classe nativa DateTime para realizar tratativas de data, retorno baseado em cenários e comparações entre datas (embora em algumas versões antigas 5.3.x do PHP, o método diff retorne bug em comparações). Hoje eu apresento a biblioteca Carbon, que nada mais é do que uma classe que estende o DateTime e traz uma série de funcionalidades legais para se trabalhar com datas.

Vamos codar, então. Criamos uma pasta chamada dates e vamos dar um composer require:

composer require nesbot/carbon

Vamos criar um arquivo date1.php e ver como o Carbon funciona:

<?php

require_once 'vendor/autoload.php'; //autoload do composer
use Carbon\Carbon; //utilizando a biblioteca Carbon

$now = Carbon::now(); //cria uma instância do Carbon com a data atual no timezone que está configurado seu PHP

$nowInTokyo = Carbon::now(new DateTimeZone('Asia/Tokyo')); //cria uma instância do Carbon com a data atual em Tóquio

$nowInLondon = Carbon::now(new DateTimeZone('Europe/London')); //cria uma instância do Carbon com a data atual em Londres

print_r($now); //retorna o valor do objeto $now

print_r($nowInTokyo); //retorna o valor do objeto 
$nowInTokyo

print_r($nowInLondon); //retorna o valor do objeto $nowInLondon

E depois vamos dar um:

php date1.php

Sendo assim, criamos três objetos com as datas e horários atuais em três timezones diferentes.

Como faríamos para criar uma data baseada em texto, por exemplo?

Vamos criar o date2.php:

<?php

require_once 'vendor/autoload.php'; //autoload do composer

use Carbon\Carbon; //utilizando a biblioteca Carbon

$firstDayOfNovember2017 = new Carbon('first day of November 2017'); //criando uma instância de primeiro de novembro de 2017

print_r($firstDayOfNovember2017); //retornando o objeto referente a primeiro de novembro de 2017

$eighthDayOfNovember2017 = $firstDayOfNovember2017->addWeek(1); //adicionando uma semana ao dia primeiro de novembro de 2017

print_r($eighthDayOfNovember2017); //retornando o objeto referente ao oitavo dia de novembro de 2017

$twentyDayOfNovember2017 = $eighthDayOfNovember2017->addDay(12); //adicionando doze dias ao oitavo dia de novembro de 2017

print_r($twentyDayOfNovember2017); //retornando o objeto referente ao vigésimo dia de novembro de 2017

Dessa forma, podemos manipular facilmente as datas, adicionando dias, semanas ou meses.

Para criar DateTimes de acordo com um valor de variáveis dia, mês, ano, horas, minutos, etc, podemos usar a sintaxe abaixo:

Carbon::createFromDate($year, $month, $day, $tz);
Carbon::createFromTime($hour, $minute, $second, $tz);
Carbon::createFromTimeString("$hour:$minute:$second", $tz);
Carbon::create($year, $month, $day, $hour, $minute, $second, $tz);

Vamos ver como ficaria para calcularmos a diferença entre os horários nas diferentes cidades:

<?php

require_once 'vendor/autoload.php'; //autoload do composer

use Carbon\Carbon; //utilizando a biblioteca Carbon

$saoPaulo = Carbon::createMidnightDate(2018, 1, 1, 'America/Sao_Paulo'); //cria uma instância do Carbon com o valor de meia noite do dia 1 de janeiro de 2018 na timezone America/Sao_Paulo

$tokyo = Carbon::createMidnightDate(2018, 1, 1, 'Asia/Tokyo'); //cria uma instância do Carbon com o valor de meia noite do dia 1 de janeiro de 2018 na timezone Asia/Tokyo

$london = Carbon::createMidnightDate(2018, 1, 1, 'Europe/London'); //cria uma instância do Carbon com o valor de meia noite do dia 1 de janeiro de 2018 na timezone Europe/London

echo ($saoPaulo->diffInHours($tokyo) . PHP_EOL); //retorna em horas a diferença entre o horário entre São Paulo e Tóquio
echo ($saoPaulo->diffInMinutes($london) . PHP_EOL); //retorna em minutos a diferença entre o horário entre São Paulo e Londres
echo ($tokyo->diffInDays($london) . PHP_EOL);  //retorna em dias a diferença entre o horário entre Tóquio e Londres

No caso acima, criamos um objeto com um horário padrão: meia-noite do dia. Só assim conseguimos calcular as diferenças de um mesmo horário com timezones diferentes. Se quisermos calcular a diferença de objetos Carbon no mesmo timezone, podemos usar os mesmos métodos apresentados acima com os objetos com diferentes horários.

Bem, galera, tem muito mais coisas que podemos fazer com o Carbon, e seria legal se você pudesse dar uma olhada na documentação da biblioteca e começar a trabalhar corretamente com datas e horas em PHP. Até a próxima!