PHP: Conversão de Datas: formato brasileiro e formato ISO

PHP: Conversão de Datas: formato brasileiro e formato ISO

Uma das principais e mais frequentes dúvidas em fóruns é sobre tratamento de datas. O formato brasileiro é dd/mm/yyy, porém os bancos de dados, por exemplo, trabalham com a data no formato ISO 8601, ou seja, yyyy-mm-dd.

Face a isso, muitos têm dúvidas em como converter do formato brasileiro para o ISO e vice-versa. É possível fazer isso de várias formas, mas pretendo mostrar aqui as principais delas, comparando o tempo de execução de cada uma, a fim de encontrar a mais eficiente.

Critério de Avaliação

Para a análise de desempenho, usarei a função microtime, que retorna o timestamp atual, em microssegundos. A lógica é armazenar na variável $time o timestamp de início da execução, para, depois, subtraí-lo do timestamp do final.

Considerarei como timestamp final o momento logo após a conversão, desconsiderando o qualquer exibição na tela. Isso porque a exibição na tela envolve acesso a periféricos (nesse caso, o dispositivo de saída, também chamado de “monitor”).

A diferença estará em microssegundos e, se for muito pequena, será mostrada em notação científica. Para forçar a exibição no formato decimal, usarei a função number_format, com precisão de 15 casas decimais.

Exemplos de Conversão de Datas

Vamos aos cinco exemplos.

O primeiro exemplo usa arrays, com as funções implode, explode, e array_reverse. É talvez o mais usado. Pelo menos é o que mais aparece por aí.

Arquivo date1.php

$time = microtime( true );
 
$date = '2011-01-15';
$dateBR = implode( '/', array_reverse( explode( '-', $date ) ) );
 
$diff = number_format( microtime( true ) - $time, 15 );
 
printf( "date1.php (dateBR = %s) | Tempo: %s", $dateBR, $diff );

O segundo exemplo usa ER’s, utilizando a função preg_replace:

Arquivo date2.php

$time = microtime( true );
 
$date = '2011-01-15';
$dateBR = preg_replace( '/([0-9]+)-([0-9]+)-([0-9]+)/', '$3/$2/$1', $date );
 
$diff = number_format( microtime( true ) - $time, 15 );
 
printf( "date2.php (dateBR = %s) | Tempo: %s", $dateBR, $diff );

O exemplo 3 usa printf e scanf (e semelhantes), sem usar variáveis auxiliares, ou seja, fazendo sscanf retornar um array, que é lido por vsprintf.

Arquivo date3.php

$time = microtime( true );
 
$date = '2011-01-15';
$dateBR = vsprintf( "%02d/%02d/%04d", array_reverse( sscanf( $date, "%d-%d-%d" ) ) );
 
$diff = number_format( microtime( true ) - $time, 15 );
 
printf( "date3.php (dateBR = %s) | Tempo: %s", $dateBR, $diff );

O exemplo 4 usa, novamente, printf e scanf (e semelhantes), mas usa variáveis auxiliares, para evitar o uso de array, da forma como é normalmente usada em linguagens como C e C++.

Arquivo date4.php

$time = microtime( true );
 
$date = '2011-01-15';
 
sscanf( $date, "%d-%d-%d", $y, $m, $d );
$dateBR = sprintf( "%02d/%02d/%04d", $d, $m, $y );
 
$diff = number_format( microtime( true ) - $time, 15 );
 
printf( "date4.php (dateBR = %s) | Tempo: %s", $dateBR, $diff );

Finalmente, o exemplo 5 usa a classe nativa DateTime, disponível a partir do PHP 5. Essa classe possui o método format, que faz a conversão entre formatos.

Arquivo date5.php

$time = microtime( true );
 
$date = '2011-01-15';
 
$DateTime = new DateTime( $date );
$dateBR = $DateTime->format( 'd/m/Y' );
 
$diff = number_format( microtime( true ) - $time, 15 );
 
printf( "date5.php (dateBR = %s) | Tempo: %s", $dateBR, $diff );

Resultado dos Testes

Vamos executar os cinco scripts e analisar as saídas deles. Note que aparecerão a data convertida e o tempo de execução de cada um deles.

Saída:

date1.php (dateBR = 15/01/2011) | Tempo: 0.000031948089600
date2.php (dateBR = 15/01/2011) | Tempo: 0.000128984451294
date3.php (dateBR = 15/01/2011) | Tempo: 0.000048875808716
date4.php (dateBR = 15/01/2011) | Tempo: 0.000030994415283
date5.php (dateBR = 15/01/2011) | Tempo: 0.000128984451294

Os números podem variar conforme o computador onde os scripts são executados, além de depender da carga da CPU no momento das execuções.

Na execução acima, o mais rápido foi o date4.php. Porém o date1.php teve quase o mesmo tempo de execução. Ambos estão lado a lado, no quesito desempenho.

Ou seja, a melhor função para converter datas seria esta:

function converteData( $data )
{
        if ( ! strstr( $data, '/' ) )
        {
                // $data está no formato ISO (yyyy-mm-dd) e deve ser convertida
                // para dd/mm/yyyy
                sscanf( $data, '%d-%d-%d', $y, $m, $d );
                return sprintf( '%d/%d/%d', $d, $m, $y );
        }
        else
        {
                // $data está no formato brasileiro e deve ser convertida para ISO
                sscanf( $data, '%d/%d/%d', $d, $m, $y );
                return sprintf( '%d-%d-%d', $y, $m, $d );
        }
 
        return false;
}

O tempo de execução pode variar de máquina para máquina. Testei em um Intel Core i7 de 2.6 GHz. Em alguns outros testes, date1.php ficou muito perto de date4.php, às vezes sendo até mais rápido. Porém na maioria das vezes o date4.php foi mais rápido.

 

The following two tabs change content below.
Graduado em Ciência da Computação, pela Universidade Federal do Paraná (UFPR), é desenvolvedor de software desde 2008, com foco em Desenvolvimento Web com PHP.