Configurações Regionais: Parece algo sem importância, mas…
Leonel Fraga de Oliveira 21/11/2009 18:53

Um belo dia, você entrega seu programa que estava funcionando perfeitamente na sua máquina de desenvolvimento e em mais algumas selecionadas pela equipe de testes, até que esse belo dia torna-se um tanto trágico: em apenas uma máquina de seu cliente ele não funciona.

Você vai, olha, e derrepente uma mensagem de erro de instrução SQL, alegando que um formato DateTime estava sendo informado de forma incorreta.

Quando chega da reunião com o usuário, você vai correndo ver o código-fonte, e constata que todas as instruções SQL que foram montadas concatenando-se strings estão tratadas, escapando todos os caracteres “cruciais”. Enfim, tudo correto.

Mas você não reparou em uma coisinha no campo que estava com problema: ele estava sendo mostrado de forma diferente na interface de usuário!

As aplicações desktop (e Web também, por que não?) são sensíveis às configurações regionais do sistema operacional.

Que catzo são essas configurações regionais?

Basicamente, são as configurações de como datas, unidades monetárias, fuso horário, números e outras coisas são apresentadas para o usuário.

Por exemplo, o formato de data do Brasil é: dia / mês / ano, sendo que o último pode ter dois ou quatro dígitos.

Vamos ao seguinte cenário:

Um programa qualquer tem um campo que se chama Data de Cadastro, que é gerado automaticamente pela interface de usuário, alimentando um textbox e o texto desse sendo concatenado em uma instrução SQL para ser persistida na base de dados. No banco de dados em questão as datas são inseridas no formato dd/MM/aaaa (normalmente, datas e horas são inseridas no formato ANSI: aaaa-MM-dd HH:mm:ss).

Na sua máquina de desenvolvimento, datas e horas são apresentados no padrão brasileiro e tudo funciona maravilhosamente bem.

Agora, na máquina do usuário, com o sistema operacional em Inglês, as datas são apresentadas no formato estadunidense e chegando o dia 13 o sistema começa a dar pau.

Vejamos, temos um SQL parecido com este na máquina de desenvolvimento quando vamos debugar o programa:

insert into TABELA (meudatetime) values (‘22/12/2009’);

O banco de dados aceita isso numa boa, porém, quando debugamos na máquina do usuário, temos o seguinte:

insert into TABELA (meudatetime) values (‘12/22/2009’);

Como esse SQL foi gerado simplesmente concatenando strings, o banco de dados entende o 22 como mês, já que ele insere datas no nosso formato brasileiro, e nem aqui, nem na China, temos o mês 22. Resultado: PAU.

Uma das formas de se resolver isso é alterando as configurações regionais do sistema operacional. No Windows, vá até o Painel de Controle e procure pela opção Configurações Regionais e de Idioma (no Windows Seven, essa opção chama-se Região e Idioma) e altere o formato de data abreviada.

Configurações Regionais

Isso resolve o nosso problema, mas e se o nosso software for para exportação, e todas as máquinas são configuradas para apresentar as configurações regionais do país em questão? Você vai forçar o seu usuário a alterar todas as máquinas, sendo que os outros sistemas estão funcionando perfeitamente?

A forma mais elegante de se resolver este problema é fazer a programação da forma correta, e aqui mostro algumas dicas:

1. Evitar a montagem de instruções SQL concatenando-se strings, e sim utilizando variáveis bind.

Utilizando uma instrução SQL estática e com variáveis bind, ou seja, uma query parametrizada, além de evitarmos ataques de SQL Injection forçamos o banco de dados a sempre trabalhar com o formato correto. Verifique a documentação do seu banco de dados ou da sua linguagem de programação para como utilizar queries parametrizadas / variáveis bind

2. Trabalhar sempre com os tipos de dados nas classes compatíveis com a base de dados.

Eu já vi programas onde o programador declarou TODAS as propriedades da classe como string e fazia a conversão de tipo quando o dado era recuperado do banco de dados (além de montar o SQL concatenado).

Declarando as variáveis com o seu tipo correspondente na base de dados, ou seja, se uma variável é do tipo TIMESTAMP na base, declare-a como DateTime, se for do tipo DOUBLE, declare como Double ou Decimal, e assim por diante. Deixe o tipo string apenas para char e varchar.

Fazendo isso, e utilizando queries parametrizadas, estaremos mantendo a compatibilidade de tipos, e o próprio mecanismo tratará de converter o que foi enviado para o formato correto.

3. Apresentar os dados na UI conforme as configurações regionais do usuário.

4. Se for utilizar SQL concatenado (é, não vai ter jeito…), formate as datas que são enviadas no banco de dados para o formato ANSI, utilizando funções de formatação de data.

Por exemplo, temos componentes do tipo DateTimePicker na tela, e este sempre apresenta as datas de acordo com a configuração regional do usuário. Caso você pegue ela em formato texto para enviar à base de dados, converta-a para o formato ANSI utilizando funções específicas que formatam datas, nada de ficar formatando com substrings. As funções específicas são projetadas para reconhecer dias, meses e anos exatamente de acordo com a configuração regional da máquina onde o programa é executado.

É, meu amigo! Parece que não, mas configurações regionais é um detalhe importante que devemos prestar atenção nas nossas aplicações!

Um abraço :)

Leonel Fraga de Oliveira Leonel Fraga de Oliveira é formado em Processamento de Dados na Faculdade de Tecnologia de São Paulo (FATEC-SP - 2002) e anteriormente em Técnico em Eletrônica, pela ETE Professor Aprígio Gonzaga (lá em 1999).
Atualmente trabalha como Analista de Sistemas na Prefeitura Municipal de São Caetano do Sul - SP
Tem como hobbies DJing (também trabalha como DJ freelancer) e ciclismo, além da manutenção dos sites NeoMatrix Light e NeoMatrix Tech.
Gosta de música eletrônica, tecnologia, cinema (super fã de Jornada nas Estrelas), gastronomia e outras coisas mais.


Compartilhe nas redes sociais

   

Deixe seu comentário

comments powered by Disqus