31
Gostei (0) (0) Buscar código fonte comentários post favorito (4) .net Magazine 120 Índice ASP.NET MVC – Criando uma aplicação multi-idiomas Veremos nesse artigo como adequar sistemas .NET aos diferentes 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 0 Curtir 0

ASP

Embed Size (px)

DESCRIPTION

ASP

Citation preview

Page 1: ASP

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

Page 2: ASP

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.

Page 3: ASP

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.

Page 4: ASP

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

Page 5: ASP

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

Page 6: ASP

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

Page 7: ASP

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

Page 8: ASP

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.

Page 9: ASP

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.

Page 10: ASP

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

Page 11: ASP

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);

Page 12: ASP

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

Page 13: ASP

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

Page 14: ASP

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

Page 15: ASP

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

Page 16: ASP

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.

Page 17: ASP

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,

Page 18: ASP

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

Page 19: ASP

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

Page 20: ASP

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

Page 21: ASP

<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

Page 22: ASP

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.

Page 23: ASP

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.

Page 24: ASP

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.

Page 25: ASP

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.

Page 26: ASP

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

Page 27: ASP

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

Page 28: ASP

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

Page 29: ASP

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

Page 30: ASP

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