Armazenando datas de uma outra forma

Esse artigo vai explicar uma forma alternativa de se armazenar datas em banco de dados. Não é uma novidade, aliás isso é coisa da galera da "old school", o pessoal que trabalhava com grande porte e coisas assim. Mas essa técnica não morreu, é bem interessante para se ter mais uma carta na manga.

[ Hits: 22.679 ]

Por: Flávio Gonçalves Garcia em 01/07/2004


Datas armazenadas como inteiro no banco



Antes de qualquer coisa, gostaria de explicar o que é unix timestamp:

É uma data em segundos de 32 bits que tem o limite mínimo (valor 0) em January 1 1970 00:00:00 GMT, que é a data marco unix (UNIX EPOCH) até Tue, 19 Jan 2038 03:14:07 GMT. Para saber a unix timestamp de uma data é só contar quantos segundos se passou da data 0 até a data desejada.

Exemplos:
No meu servidor, porque estamos falando de uma data GMT, e meu fuso-horário é o de Brasília, a data UNIX EPOCH padrão será 1969-12-31 21:00:00, três horas a menos do que o GMT.

04/02/2002 --> 1012788000
08/05/2003 --> 1052362800
25/10/2004 --> 1098669600

Voltemos ao assunto:

Ao pesquisar mais a fundo esses sistemas que a galera estava (e está) desenvolvendo, percebi que o bonitão socava um INT no campo de data. No primeiro momento isso parece meio estranho, mas se você for pensar melhor:
  • O valor do inteiro, era um UNIX TIMESTAMP;
  • Inteiros são mais rápidos de se retornar ou pesquisar do que um campo DATE/TIME TIMESTAMP, não vou discutir isso, beleza, isso é lógico;
  • Notou que o unix timestamp é justamente valor do argumento que as funções de formatação de datas do PHP precisa?;
  • Para saber a distância entre uma data e outra, é só fazer DATA_A - DATA_B, e você tem a distância (em segundos, lembrando que um minuto tem 60 segundos, uma hora 360 segundo e assim vai ... deu pra sacar!?)
  • Para compatibilidade entre bancos, isso é ótimo, executamos o select cruzão e depois fazemos as transformações no script PHP;
  • Entre outras vantagens... você vai descobrir uma a cada dia.

Guardando as datas nesse formato, teremos um script mais rápido (notaremos isso quando trabalharmos com grandes volumes de dados), e deixaremos o script mais simples (vejo isso como vantagem, tem gente que não, hehehe).

Mas nem tudo é maravilha, quando precisarmos fazer uma operação mais detalhada, com meses por exemplo, precisaremos fazer um conversão direta no SQL.

Por exemplo: todas as datas do mês de abril.

Para bancos como o MySQL isso não tem muito problema (lembrando que o CAMPO_DATA está em unix timestamp):

SELECT * FROM TABELA WHERE FROM_UNIXTIME( CAMPO_DATA ,'%m') = 4

Com MySQL temos funções que convertem para unix timestamp, mas no MS SQL Server como fica?

SELECT * FROM TABELA WHERE CONVERT(INT,MONTH( DATEADD(second, CAMPO_DATA ,'1969-12-31 22:00:00'))) = 4

Vamos mais devagar com essa aqui:

Passo 1: DATEADD(second, CAMPO_DATA ,'1969-12-31 22:00:00')
Porque usei 22:00:00 horas ao invés de 21:00:00!? Porque senão daria uma hora de diferença, só fiz uma correção, pronto está implementado o FROM_UNIXTIME do MSSQL.

Passo 2: MONTH( DATEADD(second, CAMPO_DATA ,'1969-12-31 22:00:00'))

Depois eu peguei o mês da data, beleza?

Passo 3: CONVERT(INT,MONTH( DATEADD(second, CAMPO_DATA ,'1969-12-31 22:00:00')))

Transformei o valor em inteiro.

Ou seja, quando temos esse tipo de situação, existirá uma solução para cada banco, o que não é o fim do mundo.
Página anterior     Próxima página

Páginas do artigo
   1. Eu e as datas...
   2. Datas armazenadas como inteiro no banco
   3. Conclusão
Outros artigos deste autor

Debian com Apache, PHP4, PHP5 e MySQL

I Semana de Capacitação e Desenvolvimento em Software Livre

Leitura recomendada

VirtualBox + Apache + PHP + SQL Server

Como criar um sistema de autenticação de usuários usando PHP/MySQL

Provendo dados em um servidor PostgreSQL através do Apache e PHP

PDO - Introdução e conceitos

Abordagem exemplificada à Orientação a Objetos com PHP

  
Comentários
[1] Comentário enviado por fabio em 01/07/2004 - 01:45h

Bom, como a idéia é compartilhar conhecimento, vou mostrar aqui a forma como eu faço, não digo se é melhor ou pior que a mostrada no artigo, mas também funciona muito bem!

Todos os meus arquivos possuem um include para um arquivo global de configuração do sistema, o config.inc. Nele possuo uma variável que armazena o formato do campo DATETIME do banco de dados usado pelo sistema. Por exemplo, pra MySQL defino a variável assim:

$formato_data = 'Y-m-d';

E pra SQL Server seria:
$formato_data = 'm-d-Y';

Se a regionalização mudar, basta mudar uma variável que a lógica das queries estarão automaticamente atualizadas e funcionando.

Quando vou montat um insert, faço da seguinte forma:

$data = date($formato_data);
$insert = "INSERT INTO tabela (data) VALUES ($data)";

Dessa forma não perdemos os recursos que o banco de dados oferece para cálculo de datas e nem precisamos fazer malabarismos nas queries quando mudamos de banco de dados. :P

Bom, taí outra alternativa.

[]'s

[2] Comentário enviado por ygorth em 02/07/2004 - 11:41h

Boa alternativa fabio, enquanto mais cartas nas mangas melhor.

valeu piraz, seja bem-vindo!

[3] Comentário enviado por afonso_franca em 29/09/2005 - 13:59h

Há algum tempo eu descobri o UNIX DATE também trabalhando com o banco do PHPBB e desde então tornou-se o formato padrão de data pra mim (pelo menos até 19/01/2038 hehe).

Muito boa a matéria.

[4] Comentário enviado por marcossilva em 06/10/2005 - 17:35h

Desculpa, eu não entendi algo, como eu faço para armazenar as datas no banco de dados, desta forma ??

T+

[5] Comentário enviado por RedFoot em 29/09/2007 - 23:16h

bacana Fábio

estava precisando de algo desse tipo por aqui nas novas implementações que tô buscando no site.

abraço

[6] Comentário enviado por brunoestevao em 12/03/2008 - 14:56h

$data = date('Y-m-d');
$insert = "insert into tabela (data) values ($data)";

Abraços

Bruno Estêvão
www.sempihost.com.br
Hospedagem de sites com 30 dias grátis

[7] Comentário enviado por removido em 20/04/2009 - 10:11h

muito interessante! obrigado por compartilhar


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts