Upload
elias-jr-cescon
View
7
Download
0
Embed Size (px)
DESCRIPTION
ASP
Citation preview
Gostei (0) (0)
Buscar
código fonte comentários post favorito (4)
.net Magazine 120 Índice
ASP.NET MVC – Criando umaaplicação multi-idiomas
Veremos nesse artigo como adequar sistemas .NET aosdiferentes idiomas e criar aplicações multi-idiomas,oferendo ao usuário uma experiência sempre adequada àsua realidade e preferência.
Fique por dentro
0 0Curtir0
A questão da localização em aplicações .NET é tudo sobre a representação
utilizada dentro do software. A ideia é que o usuário tenha familiaridade com o
que está sendo mostrado. No Brasil, não gostaríamos de ter uma data do tipo
mm/dd/aaaa, como é comum nos EUA, por exemplo.
É disso, e muito mais, que o conceito de localização dentro do .NET trata: como
lidar com a criação de aplicações globais. Ao longo desse artigo veremos em
detalhes o namespace System.Globalization, que traz o conceito de Cultures,
que irão controlar quase todos os aspectos desse tipo de desenvolvimento.
Hoje em dia, temos exemplos muito claros do que são aplicações globais. As lojas
de aplicações como a Windows Store permitem que as aplicações disponibilizadas
sejam distribuídas em diferentes países, com diferentes culturas e linguagens. O
problema dessa abordagem é que, normalmente, o desenvolvimento é feito tendo
em mente uma cultura, que enxerga os diferentes elementos dentro de uma
aplicação de uma forma, apenas.
Pensando nisso, temos o conceito de localização em .NET, que permite que a
cultura da aplicação seja alterada durante a execução, mudando a forma de
enxergar horários, datas, representações monetárias, textos, entre outros,
permitindo que o software seja mostrado de uma forma natural para o usuário.
Ao longo desse artigo, vamos entender como o .NET opera nesse tipo de cenário. A
ideia é que tenhamos a capacidade de criar uma página de configuração em que o
usuário irá escolher aquela cultura que mais lhe deixa confortável, o que irá alterar
todos os aspectos citados na aplicação.
Outra forma de operação, mais comum ultimamente, é a utilização da cultura do
sistema operacional em questão, sem a necessidade da criação de uma página
específica para configuração.
A vantagem da primeira abordagem está na liberdade que permite a um usuário do
Brasil, por exemplo, utilizar a aplicação em inglês americano, seja para questões de
treinamento da língua inglesa ou apenas por gosto pessoal, e por isso lidaremos
com ela. Os conceitos, entretanto, são facilmente aplicáveis a outras configurações
do gosto do leitor.
Entendendo a Localização em .NETCada linguagem falada, em qualquer lugar do mundo, possui suas regras de
formatação. Nós, como desenvolvedores, precisamos ser capazes de capturar
essas regras e colocálas para trabalhar a nosso favor dentro do produto de
software.
Se tivéssemos que criar um conjunto de regras, iríamos entender o quão complexo
isso é. Mas, para nossa sorte, o .NET Framework implementa essas regras e só o
que precisamos fazer é utilizálas. Vamos entender como essas regras são
implementam e o que fazer para utilizálas nessa seção e ao longo do artigo.
O .NET, e muitos outros frameworks e linguagens de programação, costumam
utilizar um conceito chamado de culture para a representação da linguagem alvo
da aplicação. Esse conceito consiste em um código simples, que contém uma string
com dois caracteres para representar a linguagem e dois para o país, separados
por uma vírgula ou hífen, como em “ptBR”, que representa a língua portuguesa
falada no Brasil.
É interessante notarmos que essa nomenclatura não diz respeito apenas à
linguagem escrita da aplicação, e sim a tudo que envolve a mesma. Campos
numéricos, monetários, datas, horários etc. são todos controlados por esse código
da cultura.
O .NET, especificamente, traz um conceito conhecido como neutral culture, ou
cultura neutra, que é utilizado para formatar a linguagem de uma forma mais
genérica, sem especificar o país. Por exemplo, para formatar a aplicação em
português, sem especificar o português brasileiro, bastaria utilizarmos a string “pt”.
Outro conceito importante é a cultura invariante (invariant culture), que irá ser
importante se formos guardar informações como strings. Esse conceito faz com que
a aplicação formate as strings como as escrevemos no código.
Agora que temos uma ideia geral de como é feita a implementação do sistema de
localização em .NET, vamos entrar em mais detalhes a respeito de como utilizar
essa implementação. O namespace System.Globalization traz uma classe chamada
CultureInfo, que irá controlar quase todos os aspectos da cultura da aplicação.
Essa classe é utilizada para alterar a cultura da aplicação entre uma série de
opções que podem ser vistas em “NLS API Reference”, na seção Links. Esse link
traz informações até o Windows 7, mas os Windows 8 e 8.1 podem utilizar essa
referência normalmente.
Ainda é possível a criação de nossas próprias culturas, através da classe
CultureAndRegionInfoBuilder, mas dificilmente isso será útil.
Como estamos lidando com culturas, precisamos entender como nossa aplicação
irá operálas internamente. O C# possui um conceito chamado de multithreading
(BOX 1), que em termos básicos irá permitir a criação de diversos processos da
mesma aplicação no sistema operacional.
Cada aplicação irá possuir ao menos uma thread, e é essa thread que irá controlar
a cultura de nossa aplicação. O .NET Framework traz duas diferentes culturas: uma
para a aplicação em geral, internamente, e outra para a interface de usuário.
A primeira controla a forma como números, datas, horários etc. são mostrados e a
segunda controla a linguagem que a interface de usuário será mostrada para o
usuário.
BOX 1. Multithreading
O conceito de multithreading é muito utilizado nas linguagens de alto nível
mais avançadas. Tratase da habilidade de controlar múltiplas execuções do
mesmo usuário sem criar várias cópias dos mesmos programas.
Esse tipo de processo pode auxiliar no desenvolvimento de aplicações
paralelas, que tendem a funcionar mais rapidamente, ao menos quando bem
desenvolvidas. Já o principal ponto negativo dessa abordagem é que as
threads podem interferir umas nas outras, especialmente quando ambas
acessam a memória constantemente.
Outra classe interessante dentro do namespace System.Globalization é a classe
RegionInfo. Essa classe, como o nome sugere, traz informações da região sendo
utilizada. Essas informações podem ser utilizadas dentro do código ou mesmo na
interface de usuário.
As informações são muito variadas, como se o sistema métrico é utilizado na
cultura atual ou mesmo qual é o símbolo monetário naquela cultura. Ao longo do
artigo, também a utilização dessa classe ficará mais clara para o leitor.
Com isso, podemos notar que o sistema de localização do .NET Framework é
bastante completo. Ele traz, baseado em alguns conceitos essenciais, a chance de
o desenvolvedor criar aplicações realmente globalizadas, capazes de se adaptar a
diferentes países.
Podemos apontar outra API similar, que está presente no plugin Globalize para
JavaScript. Esse plugin é mais utilizado em aplicações web, e traz uma ideia muito
similar ao que veremos para o .NET Framework.
Recursos de texto na aplicaçãoUm dos principais pontos que pensamos quando temos em mente a globalização da
aplicação é a alteração da linguagem da interface de usuário. Isso requer uma
alteração em cada um dos textos utilizados, o que pode gerar alguma dor de
cabeça se não planejamos tudo corretamente.
Entretanto, isso não é tudo. Inicialmente, podemos pensar que salvar textos em
diferentes linguagens para serem utilizados podem resolver o problema. Entretanto,
muitas vezes precisamos lidar com diferentes alfabetos, caracteres especiais, entre
outros.
Essas diferenças podem gerar problemas em vários pontos, como comparações
entre strings e a própria codificação dos caracteres (o alfabeto como o conhecemos
é codificado em ASCII, que não contém muitos dos caracteres de outras
linguagens).
A questão da comparação de string, no .NET, pode ser feita utilizando algumas
propriedades da classe StringComparison. Essa classe pode utilizar elementos
genéricos para a comparação, que irão funcionar em qualquer cultura, ou
elementos específicos da cultura, que podem gerar problemas.
Já a questão da codificação pode ser resolvida com a utilização de alguns métodos
e propriedades da classe Encoding. Nesse caso, entretanto, precisamos ter alguma
noção dos diferentes padrões, especialmente o UTF8 e o ASCII.
Essas questões devem ser utilizadas com um recurso das aplicações .NET: os
resource files, ou arquivos de recursos. Esses arquivos serão utilizados para
guardar as diferentes strings utilizadas dentro da aplicação, desde o mais simples
“Olá Mundo!” utilizado na página inicial até o texto mais obscuro de uma página
que nem será acessada.
O sistema do .NET permite a criação de vários arquivos desse tipo, e todos eles
terão o mesmo nome, com uma ressalva: o nome do arquivo será seguido pela
cultura utilizada, algo como “Recursos.resx” para o padrão (português do Brasil) e
“Recursos.enUS.resx”, para inglês americano, por exemplo. Esses elementos
seriam acessados diretamente do código através do nome desse arquivo de
recursos.
Por exemplo, se tivéssemos uma string com o nome de Olá em nosso arquivo .resx,
iríamos acessála por “Recursos.Olá”. Isso ficará mais claro quando lidarmos com
arquivos de recursos.
A questão desses arquivos também está sujeita a outros conceitos dentro das
aplicações. Por exemplo, há o conceito de localidade e globalidade de recursos. O
primeiro só estará disponível para uma determinada gama de páginas (ou janelas)
e o outro, como nome sugere, será global, para toda a aplicação.
A ideia dos recursos de texto é clara: tornar o mais claro e perfeito possível a
alteração da cultura da aplicação. O ideal é que a aplicação seja capaz de se
adaptar aos mais diferentes cenários, podendo funcionar em diferentes alfabetos,
com caracteres especiais, como o que vemos em países como Suécia, Turquia ou
Japão.
Ao longo de nosso artigo, vamos observar como lidar com essas culturas que
diferem mais da nossa, e evitar que essas diferenças nos caracteres travem a
aplicação ou façam a mesma dar um resultado diferente do esperado.
Criando uma aplicação básicaNesse momento, temos uma ideia geral de como o sistema de localização do .NET
Framework funciona. A ideia é que coloquemos essas ideias em prática e vejamos
como as aplicações irão se comportar com diferentes configurações de culturas.
Conforme comentamos, esse tipo de abordagem para criação de aplicações é muito
comum especialmente nas aplicações Windows Store e Windows Phone, que podem
estar disponíveis em todos os países do mundo.
Porém, como os conceitos também são utilizáveis em outras tecnologias,
estaremos criando um exemplo baseado em uma aplicação do tipo Console, a mais
simples que há. A adaptação desses conceitos a outras tecnologias .NET é bastante
simples.
Vamos utilizar o template comum de aplicações Console, como mostra a Figura 1.
A criação é bastante simples: estaremos chamando nossa aplicação de
“ExemploLocalizacaoNET”. Com isso, temos nosso projeto pronto para ser
configurado de forma a utilizar os conceitos de localização em .NET.
NOTA: As aplicações para as lojas do Windows estão ainda mais simples de
serem desenvolvidas. A Microsoft disponibilizou recentemente o template
universal de aplicações, que permite a criação de software para Windows 8.1 e
Windows Phone 8.1 baseados em um só projeto.
Esse tipo de aplicação é muito interessante para ser utilizado com os conceitos
de localização, criando uma aplicação que irá abranger uma área muito grande,
com grandes possibilidades de aumento do ganho do desenvolvedor.
O conceito de aplicações universais tem ganhado muita força no desenvolvimento
.NET. A Microsoft tem anunciado várias ações para tornar o .NET Framework mais
aberto, capaz funcionar em diferentes plataformas.
No caso dessas aplicações universais, o template do Visual Studio irá criar uma
solução baseada em três projetos: um projeto de aplicação Windows Store, outro
para Windows Phone e um projeto compartilhado entre os demais.
A ideia é que, devido à proximidade das plataformas (Windows e Windows Phone
8.1), os recursos da aplicação sejam salvos em apenas um projeto, aumentando o
reuso de código e também a utilização das lojas de aplicativos da Microsoft.
abrir imagem em nova janela
Figura 1. Criando projeto Windows Store
Nesse momento, em nossa aplicação exemplo, vamos criar uma interface
extremamente básica, com alguns textos simples. Além disso, criaremos também
um menu de configuração, que irá permitir ao usuário escolher a cultura desejada
posteriormente.
A ideia é que, inicialmente, tenhamos uma interface que reflita as alterações nas
culturas que o menu de configuração irá proporcionar à aplicação. Essas alterações
serão vistas no texto inicial de boasvindas e na data sendo mostrada no topo da
aplicação, como mostra a Figura 2. O primeiro item de menu diz respeito à
atualização dos dados para verificarmos se houve alguma alteração na cultura.
Isso não acontecerá (a não ser que haja algum problema ou que a cultura seja
alterada no próprio Windows), é apenas uma forma de atualizar a página e as
informações nela contidas. É importante notarmos a questão do formato de datas
na Figura 2.
Esse formato é do tipo AAAAMMDD, com o horário em 12 horas, o que condiz com
a cultura inicial de nossa aplicação. Essa cultura é a “enCA”, ou inglês canadense.
No caso do leitor, essa cultura deve estar como “ptBR”, uma vez que a aplicação
irá utilizar a cultura do Sistema Operacional para formatar os elementos dentro do
software.
Figura 2. Página inicial
Agora que temos nosso menu inicial, vamos criar um menu de configuração. A
aplicação está esperando uma opção que irá levar a mesma para uma página de
configurações. A estrutura do menu de configurações é bastante simples:
estaremos adicionando as linguagens “Português do Brasil”, “Inglês Americano” e
“Espanhol da Espanha”.
Essas variações referentes ao país trazem ainda outras informações, que fazem
com que a aplicação se comporte como os usuários desses países esperam. Note
que apenas o formato da interface de usuário está pronto, com o comportamento
interno ainda por ser definido.
Assim, temos nossa aplicação preparada para a utilização do sistema de
localização em .NET. Nas próximas etapas de nosso artigo, iremos trazer em
detalhes como lidar com essa API e utilizar as páginas que acabamos de criar para
termos uma aplicação verdadeiramente globalizada.
Entendendo o uso das culturesConforme comentamos, a aplicação utiliza a cultura do Sistema Operacional por
padrão. Essa cultura irá definir como a interface de usuário irá se comportar.
Entretanto, ela não é a única. O Windows permite a alteração de uma “cultura de
formatação”, que não irá afetar a interface de usuário, apenas a forma como datas,
horários, valores numéricos e monetários, entre outros, serão mostrados no SO.
Isso condiz com a forma de programação que comentamos, onde há dois tipos de
culturas dentro de nossa aplicação: a cultura da aplicação em si, utilizada
internamente (CurrentCulture) e a cultura da interface de usuário
(CurrentUICulture). Essa primeira é a que será alterada se alterarmos a preferência
de formatação na Figura 3. Entretanto, como podemos notar, o Windows mesmo
recomenda que não alteremos essa propriedade, mantendo o padrão, que é a
mesma linguagem de interface do Windows.
Figura 3. Alterando formatação do SO
Essa formatação, mesmo que alteremos o seu valor, não irá afetar uma
propriedade importante dentro do namespace System.Globalization, em especial na
classe CultureInfo. Essa propriedade, InstalledUICulture irá retornar a cultura que o
SO foi instalado, o que pode facilitar a recuperação de um padrão inicial por parte
da aplicação, se necessário.
Note que esse valor não reflete a cultura sendo utilizada no momento (no meu
caso, inglês canadense (enCA)) e sim a que o Sistema Operacional foi instalada
(no meu caso, inglês americano (enUS)). Essas ligeiras alterações nos conceitos
necessitam de um entendimento para que não haja confusão na hora do
desenvolvimento.
O sistema de localização em .NET permite a utilização de dois tipos especiais de
culturas: a cultura neutra (neutral culture) e a cultura invariante (invariant
culture). Esses dois tipos possuem suas utilizações e podem ser muito úteis em
vários casos. Vamos começar pela cultura neutra. Relembrando, esse tipo de
cultura não identifica o país de origem, apenas a língua escolhida.
No caso, vamos estar trabalhando apenas com “pt” ou “en” ao invés de “ptBR” ou
“enUS” (ou “enCA”). Esse tipo de colocação pode ser muito útil, especialmente
quando estamos utilizando uma forma fixa de formatação de dados de datas e
horários, por exemplo. A utilização dessa cultura neutra pode ser visualizada na
Listagem 1 e na Figura 4. Podemos notar que alteramos a cultura de nossa
aplicação para uma cultura neutra, sem a definição de país. Também podemos
observar que o formato de datas e horários está diferente, respeitando o que a
cultura “pt” diz.
O leitor pode notar que, se tentarmos acessar a propriedade “CurrentUICulture” da
Thread, ela não terá sido alterada. Isso mostra de forma ainda mais clara que não
há uma correspondência entre os dois tipos de cultura. Ainda, se alterássemos essa
segunda cultura (CurrentUICulture), não haveria nenhuma alteração no formato das
datas sendo mostradas em nossa aplicação.
Listagem 1. Utilização de neutral culture
Thread.CurrentThread.CurrentCulture = new CultureInfo("pt"); Console.WriteLine("Cultura atual: " + Thread.CurrentThread.CurrentCulture); Console.WriteLine(DateTime.Now);
Figura 4. Cultura neutra (“pt”)
A utilização da cultura invariante (invariant culture) é ainda mais simples. Esse tipo
de cultura é definido através de uma propriedade na classe CultureInfo, chamada
InvariantCulture. A utilização dessa propriedade é feita diretamente no elemento
que queremos mostrar, como mostra a Listagem 2. Não há nenhuma alteração da
cultura da aplicação; apenas aplicamos esse tipo de cultura invariante localmente.
Nesse caso, o resultado é o número sendo mostrado exatamente como lidamos
com ele no código (1.78). Caso utilizássemos uma cultura como a “ptBR”, por
exemplo, teríamos o número “1,78”, sendo mostrado. A utilização desse elemento
pode ser útil em alguns casos, mas mais para questões de depuração de código.
Listagem 2. Utilização de invariant culture
var num = 1.78; num.ToString(CultureInfo.InvariantCulture); Console.WriteLine(num);
Como podemos notar, a classe CultureInfo é responsável pelo controle de quase
tudo que diz respeito à globalização dentro do namespace System.Globalization.
Essa classe traz todos os elementos necessários para alteração e obtenção da
cultura sendo utilizada pelo Sistema Operacional, o que facilita a vida do
desenvolvedor no acesso a essas informações.
Além disso, a utilização dos dois tipos “especiais” de culturas (neutra e invariante),
permitem uma liberdade ainda maior no que diz respeito à formatação de dados.
Isso porque mostramos que não precisamos estar presos em apenas uma cultura,
ou formato de dados, dentro da aplicação.
Por dentro da classe RegionInfoPudemos notar que a classe CultureInfo é a responsável por quase tudo que diz
respeito à globalização em .NET. Entretanto, ela não é a única classe com
importância nesse meio. A classe RegionInfo é outra que traz diversos elementos
muito úteis para o desenvolvimento.
É essa classe que irá nos informar, por exemplo, se a região ou país em questão
(definido na CurrentCulture) utiliza o sistema métrico, nome e símbolo da moeda da
região, entre outras informações úteis. A utilização da segunda, em especial, é
muito importante em uma aplicação globalizada. Isso porque dificilmente
estaremos lidando com dólares se moramos no Brasil, ou reais se moramos em
outro país qualquer, por exemplo.
Vamos observar que a Tabela 1 traz as principais propriedades da classe
RegionInfo. Repare que existem diversas informações úteis, dependendo do tipo de
aplicação sendo desenvolvida. De qualquer forma, são informações que podem ser
utilizadas em diversas situações para garantir que a globalização seja respeitada.
Vale ressaltar que essas propriedades não são estáticas, ou seja, não estão
vinculadas à classe RegionInfo e sim a um objeto RegionInfo. Esse objeto,
normalmente, é o CurrentRegion, que contém as informações da região da cultura
atual.
Nome Descrição
CurrencyNativeName Nome nativo da moeda local
CurrencyEnglishName Nome, em inglês da moeda local
CurrencySymbol Símbolo da moeda local
IsMetric Booleano que indica se a região ou país utiliza o sistema
métrico
ISOCurrencySymbol Símbolo da moeda local em três letras conforme a norma
ISO 4217
ThreeLetterISORegionName Código do país ou região em três letras, conforme a norma
ISO 3166
NativeName Nome, na linguagem nativa, no país ou região
Tabela 1. Principais Propriedades de RegionInfo
Como foi possível notarmos, a classe RegionInfo possui diversas propriedades
interessantes. Vamos analisar algumas delas na prática e verificarmos se condizem
com o que esperamos em nosso país.
Estaremos utilizando o código da Listagem 3. Note que estamos utilizando o
símbolo monetário dos reais (linha 02) e que ele condiz com o esperado para o
Real. Entretanto, para uma questão de globalização, esse código pode não
funcionar. Isso porque, para alguns países, o símbolo da moeda local costuma
aparecer após o valor digitado.
Como isso não é muito comum, um código assim irá funcionar na maior parte dos
lugares. Um código como o da linha 03 pode funcionar melhor mundialmente, com a
ressalva de que o resultado se dará no singular, independentemente do valor
escolhido.
Na linha 04 podemos notar que a informação passada está correta: o Brasil utiliza o
sistema métrico. O resultado desse código pode ser visto na Figura 5.
Listagem 3. Utilizando classe RegionInfo
01 var infoRegiao = new RegionInfo("pt‐BR"); 02 Console.WriteLine("Temos " + infoRegiao.CurrencySymbol + "27,45"); 03 Console.WriteLine("Temos 27,45 " + infoRegiao.CurrencyNativeName); 04 Console.WriteLine("Utiliza sistema métrico: " + infoRegiao.IsMetric);
Figura 5. RegionInfo na prática
As informações desse exemplo estão apenas sendo mostradas para nós. O ideal é
que elas sejam utilizadas para algum tipo de configuração dentro da aplicação.
No caso do booleano que indica se o sistema métrico é utilizado, especialmente, é
possível utilizarmos algum tipo de cláusula “if” para validar uma informação de
comprimento entrada pelo usuário, por exemplo.
Precisamos notar que as informações estão lá para serem utilizadas, e precisamos
saber como tirar proveito delas.
Representações de data, horários, valoresnuméricos e monetáriosA forma como os dados são representados dentro da aplicação é uma das principais
vantagens da utilização do sistema de localização do .NET. As representações de
data, horários, valores numéricos e monetários é uma das questões que mais
trazem problemas quando tratamos de um ou outro tipo.
Por sorte, o sistema de localização pode controlar esses fatores para nós. Como
observamos, as datas e horários são automaticamente alteradas quando alteramos
a cultura de nossa aplicação. O mesmo é válido para os valores numéricos e
monetários.
Como comentamos, a utilização da cultura é necessária para garantir que tudo
dentro da aplicação seja natural para o usuário, independentemente do país em
que ele vive.
Vamos começar falando de datas e horários. O formato padrão desses dois
elementos em aplicações é através de um tipo de dado chamado de DateTime.
Esse tipo de dado possui uma representação para a data seguida por uma
representação do horário.
Essa representação irá variar conforme a cultura estipulada. Porém, o formato
padrão de tempo e data segue o ISO 8601, que especifica um formato de data e
hora em que a ordem deve ser do mais significante para o menos: AAAAMMDD
para data e HH:MM:SS para hora.
Esse tipo de formato é utilizado em alguns países, enquanto outros preferem outros
formatos. No caso do Brasil, temos o formato de data diferente desse padrão,
utilizando o padrão DD/MM/AAAA.
Observe o código da Listagem 4 e note que estamos utilizando a variável “agora”
para representar a data e hora atual (DateTime.Now). A questão toda está nos
métodos ToString().
Repare as linhas 02 a 04: primeiramente, estamos trazendo a data e hora de forma
conjunta, e então apenas a data e por fim apenas o tempo. Como não estamos
realizando nenhum tipo de definição explícita da cultura, a data e hora está sendo
mostrada no formato da cultura atual da Thread.
Porém, na linha 06 estamos realizando essa definição de forma explícita. Estamos
indicando que desejamos seguir o formato de data e hora utilizado na cultura “pt
BR”, que estamos acostumados. Como o comentário da linha 05 indica, esse tipo de
definição explícita é errado, uma vez que quebraria completamente o conceito de
globalização da forma como o .NET Framework o propõe.
A ideia é sempre permitir que a data e hora da aplicação sejam controlados pela
propriedade CurrentCulture da thread atual.
Listagem 4. Representação de data e hora
01 var agora = DateTime.Now; 02 Console.WriteLine(agora.ToString()); 03 Console.WriteLine(agora.ToShortDateString()); 04 Console.WriteLine(agora.ToShortTimeString()); 05 // Errado 06 Console.WriteLine(agora.ToString(new CultureInfo("pt‐BR")));
Na questão de data e hora, podemos ressaltar alguns formatadores que podem ser
utilizados. Um deles é o formatador “R”, que pode ser utilizado como mostrado na
Listagem 5. Esse formatador irá alterar o formato de data e hora para um mais
completo, de acordo com o formato RFC1123 (<dia_da_semana>, <dia_do_mês>
de <mês> de <ano> <horário> <fuso_horário>; por exemplo, SextaFeira, 16 de
janeiro de 2015 10:00:00 GMT). Existem outros formatadores que acabam não
vindo ao caso nesse momento, uma vez que a questão da data completa é o que
temos de mais comum em termos de utilização.
Listagem 5. Formatador “R”
Console.WriteLine(agora.ToString("R"));
Outro ponto que requer atenção é o parsing de datas. Como existem diversos
formatos, uma data como “02/01/2015” pode ser interpretada tanto como “2 de
janeiro” como “1º de fevereiro”, dependendo da cultura em questão. Isso pode
levar a problemas internos na aplicação.
Uma forma de evitar esses problemas é a utilização do método
DateTime.ParseExact(), que irá receber como parâmetros a data, o padrão a ser
formatado e a cultura em questão, como mostra a Listagem 6. É interessante a
utilização desse método dentro de blocos try/catch, uma vez que a change de
problemas durante o parsing de datas é grande.
Listagem 6. Utilização do método ParseExact()
var data = DateTime.ParseExact("02/01/2015", new CultureInfo("en‐US").DateTimeFormat.ShortDatePattern,
new CultureInfo("en‐US")); Console.WriteLine(data);
A questão do número das semanas é outra necessita de atenção. Como em alguns
países a semana começa no domingo e em outros na segundafeira, isso pode
causar erros no número da semana se o ano começou em um desses dois dias. Por
exemplo, o ano de 2012 começou em um domingo.
Isso faz com que países em que a semana começa na segundafeira tenham
diferentes números de semana ao longo do ano. Por exemplo, no Brasil a semana
começa no domingo. Isso faria com que os números de semana fossem diferentes
dos vistos na Suécia, onde a semana começa na segundafeira.
Vale ressaltar que essa questão é apenas interna do sistema de globalização do
.NET, e não diz respeito aos números reais das semanas. Em outras palavras, a
primeira semana do ano é a mesma no Brasil e na Suécia.
Quanto aos valores numéricos e monetários, também é necessária alguma atenção.
A utilização da cultura invariante (invariant culture), como vimos anteriormente,
elimina problemas de formatação, utilizando os mesmos números que utilizamos
para a programação.
Entretanto, muitas vezes isso não é interessante para o usuário, uma vez que ele
espera enxergar os valores de uma forma com a qual está acostumado. Pensando
nisso, precisamos entender quais são as alterações que acontecem nos valores
numéricos e monetários ao utilizarmos o sistema de globalização do .NET.
Vamos utilizar, como mostra a Listagem 6, o número 2.456.000,57 (dois milhões
quatrocentos e cinquenta e seis mil vírgula cinquenta e sete). Repare que o
formato com que estamos acostumados separa as centenas dos milhares, os
milhares dos milhões etc. utilizando o “.”.
Já as casas decimais são separadas através da vírgula. Em outras culturas, como
nos Estados Unidos, as casas decimais são separadas através do ponto “.”, como
vemos em todas as linguagens de programação (ao menos as que eu conheço), e
as centenas dos milhares, milhares dos milhões etc., são separadas através de
vírgula. Outras ainda costumam separar as centenas dos milhares, e assim
sucessivamente, através de um espaço simples.
A Listagem 6 ainda traz um outro elemento, o parâmetro “N” na chamada do
método ToString(). Esse parâmetro é utilizado para indicar que se trata de um
valor numérico, para que ele seja formatado de acordo. Outros parâmetros podem
ser utilizados para diferentes situações, como em casos de valores monetários.
Esses parâmetros podem ser conferidos na seção Links. Repare na Figura 6 a
amostragem dessa questão.
Listagem 6. Código para formatação numérica
var num = 2456000.57; Console.WriteLine(num.ToString("N", new CultureInfo("en‐US"))); Console.WriteLine(num.ToString("N", new CultureInfo("pt‐BR")));
Figura 6. Amostragem de valores numéricos
Quando falamos da classe RegionInfo, mencionamos o símbolo monetário da
região. A utilização dada tinha um problema, uma vez que o símbolo pode vir tanto
na frente do valor como atrás, dependendo da cultura utilizada. Para resolver esse
problema, o ideal é que utilizemos o método ToString() com o parâmetro “C” (de
Currency) e suas variações.
Isso fará com que o valor monetário seja formatado como é esperado na cultura
em questão. Por exemplo, se, ao invés do “N” no código da Listagem 6
tivéssemos o “C2”, teríamos um resultado similar ao mostrado na Figura 7. O
número após o parâmetro “C” indica o número de casas decimais a serem
mostradas. Se utilizássemos a cultura sueca (“svSE”), por exemplo, teríamos o
resultado mostrado na terceira linha de valores na figura.
A utilização dessa cultura se dá pelo fato de o indicador da moeda vir depois nela.
Figura 7. Valores monetários
Como podemos notar, existem diversas configurações possíveis para valores
numéricos, monetários, de data ou hora. A ideia é que o desenvolvedor tenha
liberdade para lidar com esses valores da forma com que desejar.
É claro que é preciso atenção para não quebrar a utilizada do sistema de
globalização que o .NET nos oferece. Mas os elementos trazem elementos
interessantíssimos para a criação de uma interface de usuário mais próxima do que
ele espera e está acostumado no dia a dia.
Desenvolvendo o menu de configuraçãoComo o leitor pode ter reparado, acabamos deixando nossa aplicação exemplo
meio de lado para exemplificar os elementos importantes do sistema de localização
do .NET. Agora que conhecemos os conceitos e como eles operam, a ideia é aplicá
los de forma a criar uma aplicação simples, mas globalizada, capaz de funcionar
utilizando as culturas americana, brasileira e espanhola.
A estrutura do mesmo já está pronta; precisamos apenas fazer com que a escolha
que o usuário faz importe, ou seja, com que a cultura seja alterada uma vez que o
usuário escolha uma diferente cultura.
Vamos começar definindo a cultura padrão de nossa aplicação. Essa cultura será
definida em nosso arquivo App.config, com um código como o da Listagem 7.
Podemos notar que demos um nome para essa cultura e, embora esse nome seja
similar ao utilizado pela Thread, eles não são vinculados diretamente. Precisaremos
realizar essa vinculação posteriormente, de forma manual.
Isso que foi definido aqui é uma configuração da aplicação, como a tag
<appSettings> sugere. Não tem ligação direta nenhuma com a classe CultureInfo
ou qualquer outra informação sobre localização do .NET.
Listagem 7. Cultura padrão em App.config
<appSettings> <add key="DefaultCulture" value="pt‐BR"/> </appSettings>
Agora que temos o valor definido, vamos utilizálo em nossa aplicação. O ideal,
independentemente do tipo de aplicação, é realizar essa definição antes da
inicialização dos componentes. No caso de uma aplicação Console, isso é feito no
começo do método Main(). Para isso, precisamos buscar o valor de “DefaultCulture”
nas configurações das aplicações.
Para isso, basta acionarmos o ConfigurationSettings.AppSettings, como mostra a
Listagem 8. A informação é que o ConfigurationSettings está obsoleto e que o
ideal é a utilização do ConfigurationManager. Entretanto, você pode utilizar
qualquer um dos dois sem problema nenhum, ao menos por enquanto. A seguir, a
cultura obtida está sendo utilizada para os valores de CurrentCulture e
CurrentUICulture.
Listagem 8. Definição da cultura padrão
// Definição da cultura padrão CultureInfo defaultCulture = new CultureInfo(ConfigurationSettings.AppSettings["DefaultCulture"]); Thread.CurrentThread.CurrentCulture = defaultCulture; Thread.CurrentThread.CurrentUICulture = defaultCulture;
NOTA: A definição da cultura padrão pode não ser necessária em alguns casos
em que a cultura do Windows é a ptBR. Entretanto, como não sabemos de
antemão (teoricamente) onde nossa aplicação irá rodar, é interessante
definirmos explicitamente.
O próximo passo é a utilização do menu de configurações criado para alterar essa
cultura de acordo com o que foi proposto. Para isso, temos um código como o da
Listagem 9. Repare que estamos utilizando um bloco switch/case para as opções
de 1 a 3, e que para qualquer outra opção ele irá informar que a opção é inválida.
Para cada uma das línguas, estamos resetando as culturas da UI e a cultura da
aplicação em geral. Quando executamos, podemos notar que a cultura é alterada.
Entretanto, não notamos muitas diferenças na interface, apenas quando
observamos a data e a hora, que estão sendo mostradas.
Listagem 9. Configuração do menu de configurações
Console.WriteLine("Menu de configurações:"); Console.WriteLine("1 ‐ Português do Brasil\n2 ‐ Inglês Americano\n3 ‐ Espanhol da Espanha"); int y = int.Parse(Console.ReadLine()); CultureInfo culture; switch(y) case 1: culture = new CultureInfo("pt‐BR"); Thread.CurrentThread.CurrentCulture = culture; Thread.CurrentThread.CurrentUICulture = culture; break; case 2: culture = new CultureInfo("en‐US"); Thread.CurrentThread.CurrentCulture = culture; Thread.CurrentThread.CurrentUICulture = culture; break; case 3: culture = new CultureInfo("es‐ES"); Thread.CurrentThread.CurrentCulture = culture; Thread.CurrentThread.CurrentUICulture = culture; break; default: Console.WriteLine("Opção inválida!"); break;
Notamos que a configuração do menu para alteração da cultura da aplicação é
bastante simples. Basta que utilizemos o conceito já discutido anteriormente e
definir a nova “CurrentCulture” da thread atual.
A forma como a aplicação está definida faz com que o menu seja mostrado
constantemente, permitindo a alteração da cultura, apenas para verificação dos
elementos.
Vale notarmos que não há uma restrição quanto ao número de línguas (ou culturas)
que uma aplicação pode suportar. O ideal é que tenhamos o máximo possível,
dentro de uma limitação natural de espaço em disco para armazenamento e escopo
da mesma.
Criando arquivo de recursos para a UIUm dos passos mais importantes para a criação de uma aplicação realmente
globalizada está nos arquivos de recursos. Esses arquivos são utilizados para
salvar as strings da interface de usuário da aplicação nas várias linguagens que a
mesma utiliza.
Vale notarmos que essa ideia não é exclusiva para globalização: mesmo em
aplicações com uma cultura podem tirar proveito da melhor organização que os
arquivos .resx trazem.
Atualmente, nosso arquivo exemplo possui algumas strings de interface de usuário.
São as strings do menu inicial, as strings do menu de configuração e as strings de
boasvindas. Iremos adicionar essas strings, que atualmente estão no código, a um
arquivo .resx.
Vamos começar com um arquivo inicial, chamado Strings. Para isso, clicamos com
o botão direito sobre o projeto, e então em “Add>New Item”. Nessa janela, basta
escolher o tipo “Resources File”, como mostra a Figura 8. Com isso, temos a
criação de um arquivo que espera alguns detalhes das strings de nossa aplicação.
abrir imagem em nova janela
Figura 8. Criando arquivo de recursos
A ideia é adicionarmos todos os textos de nossa aplicação a esse arquivo de
recursos. O nome deles não é muito importante, mas é preciso que saibamos quais
são para utilização dentro do código. Na Figura 9, o arquivo Strings.resx completo,
com todas as strings que iremos utilizar. Note que esse é o arquivo padrão: ele
será utilizado quando não houver um arquivo específico para a cultura atual
(CurrentUICulture).
Note que a quantidade de recursos é bastante alta com relação a complexidade da
aplicação. Isso é porque existem vários textos dentro da aplicação, por menor que
ela seja. Em uma aplicação complexa, esses arquivos de recursos serão bastante
extensos, o que aumenta a necessidade de começarmos a desenvolver pensando
neles, e não inserilos em uma etapa posterior.
Ainda na mesma figura, notamos que podemos adicionar comentários a respeito
dos elementos. Isso pode ser interessante em aplicações maiores, para que
tenhamos uma melhor ideia de aonde estamos utilizando o recurso em questão.
abrir imagem em nova janela
Figura 9. Arquivo Strings.resx
O próximo passo é a criação dos arquivos de recursos específicos de cada uma das
culturas definidas. Para isso, uma regra de nomeação precisa ser respeitada: o
nome deve ser o mesmo (Strings) do arquivo padrão, com o sufixo (língua, como
.ptBR).
A aplicação irá entender que esse sufixo indica que o arquivo de recursos para
aquela cultura é esse. Note na Figura 10 que os nomes dos arquivos criados. Aqui,
vale um macete: é interessante simplesmente copiar e colar o arquivo de recursos
criado inicialmente quantas vezes for necessário e o renomear.
Isso garante que o identificador das strings (Name) continuará o mesmo, bastando
que alteremos o conteúdo dos mesmos.
Figura 10. Nomenclatura dos arquivos .resx
Agora que temos os arquivos de recursos prontos, precisamos utilizálos dentro de
nosso código. Podemos notar que é bastante simples essa utilização: eles
funcionam como classes, e cada um dos elementos são como as propriedades.
Como podemos notar no trecho da Listagem 10, estamos utilizando a string
“BoasVindas” para representar a frase de boasvindas de nossa aplicação: “Bem
vindo à localização em .NET!”.
Além disso, estamos mostrando o menu principal de nossa aplicação. As demais
strings podem ser utilizadas da mesma forma: <Nome_do_arquivo_resx>.
<Name>, como por exemplo “Strings.MenuConfigsCabecalho”.
Listagem 10. Utilização dos recursos do arquivo Strings
Console.WriteLine(Strings.BoasVindas); Console.WriteLine(Strings.MenuPrincipalAtualizar); Console.WriteLine(Strings.MenuPrincipalConfigs); Console.WriteLine(Strings.MenuPrincipalSair);
Temos as strings definidas como sendo nossos recursos. Vamos analisar o que
acontece em nossa aplicação quando alteramos a cultura do mesmo. Lembrese
que, inicialmente, temos a cultura “ptBR” sendo utilizada. A Figura 11 mostra as
execuções da aplicação nas culturas “ptBR” e “enUS”. É possível notarmos que a
data e hora também foram alteradas de acordo com a cultura definida.
Figura 11. Execução em diferentes culturas
Com isso, temos que a criação de aplicações capazes de executar em diferentes
culturas não é só possível como, de certa forma, simples. A grande sacada é que
precisamos conhecer um pouco da cultura dos paísesalvo, de modo a não termos
surpresas que podem comprometer a qualidade de nossa aplicação.
No caso dos arquivos de recursos, é bastante simples a criação de vários deles.
Porém, precisamos levar em consideração a questão do maior espaço em disco que
uma aplicação com vários desses arquivos irá ocupar, especialmente em aplicações
para dispositivos móveis.
Ao longo desse artigo trouxemos em detalhes o namespace System.Globalization,
do .NET Framework. A ideia foi trazer para o leitor as possibilidades que esse
namespace nos traz, em termos de globalização da aplicação.
Com o advento das lojas de aplicativos, esse tipo de abordagem é muito
interessante, porque permite a nós, desenvolvedores, um mercadoalvo mais
amplo, o que aumentará nosso rendimento.
O tipo de abordagem mostrado ao longo do artigo, criando aplicações globais, é
especialmente comum em dispositivos móveis. Agora, com o Windows 8 e 8.1, a
ideia desse tipo de aplicação tende a ganhar espaço.
Além disso, a alteração da cultura da aplicação, modificando linguagem e o formato
dos elementos numéricos e de data e hora, é especialmente importante em
website. Os conceitos mostrados podem ser utilizados em todas essas plataformas.
Por fim, não poderíamos deixar de mencionar o plugin Globalize para JavaScript.
Esse elemento é bastante similar ao namespace System.Globalization, mas pode
ser utilizado em vários tipos de aplicações, sendo mais voltado para o
desenvolvimento web.
Esse plugin pode ser utilizado pelo cabeçalho HTML <script
src="http://ajax.aspnetcdn.com/ajax/globalize/0.1.1/globalize.min.js" />. O
conceito de culturar e regiões é muito similar ao que vimos ao longo do artigo, com
algumas alterações. Para mais informações a respeito, cheque a seção Links.
Links
NLS API Reference
http://msdn.microsoft.com/enus/goglobal/bb896001.aspx
Padrão de formatos numéricos de string
http://msdn.microsoft.com/ptbr/library/
dwhawy9k%28v=vs.110%29.aspx
Gostei (0) (0)
O que você achou deste post?
Plugin Globalize
https://github.com/jquery/globalize
Henrique Machado Gasparotto
Estudante de Engenharia de Computação na Universidade Federal de Santa Maria – UFSM e Técnico emInformática pelo SENAC Santa Maria. Experiência em programação C# .NET e Java, além de aplicaçõesmobile (Android e Windows Phone) e [...]
Comentário | Tire sua dúvida
Serviços
Inclua um comentário
Adicionar aos Favoritos
Marcar como lido/assistido
Incluir anotação pessoal
Versão para impressão
+.net
Mais postsRevista
Revista .net Magazine 120
Artigo
DDD ASP.NET: Criando um repositório de dados - Parte 3
Artigo
Entity Framework: Aplicando o padrão de projeto MVVM
Artigo
Conheça o Azure WebJobs
Artigo
Criando um carrinho de compras com KnockoutJS e SignalR
Artigo
ASP.NET MVC Mobile – Modos de visualização eperformance – Parte 2
Video aula
Profile - Curso básico de ASP .NET - Aula 67
Video aula
Cache - Curso básico de ASP .NET - Aula 66
Video aula
Session - Curso básico de ASP .NET - Aula 65
Listar mais conteúdo
Anuncie | Loja | Publique | Assine | Fale conosco
Hospedagem web por Porta 80 Web Hosting
DevMedia
Você curtiu isso.
Você e outras 54.323 pessoas curtiram DevMedia.
Plugin social do Facebook
Curtir