Como localizar números corretamente?


38

Quais advertências devo estar atento ao localizar números no meu aplicativo front-end?

Exemplo: em português do Brasil (pt-BR), dividimos milhares com pontos e decimais com vírgulas. No inglês dos EUA (en-US), é o contrário. Em pt-BR, apresentamos os dígitos separados por milhares, o mesmo que en-US. Mas lendo sobre o inglês indiano (en-IN) hoje me deparei com esta jóia:

O sistema de numeração indiano é o preferido para o agrupamento de dígitos. Quando escritos em palavras ou quando falados, números inferiores a 100.000 / 100.000 são expressos da mesma forma que no inglês padrão. Os números incluindo e além de 100.000 / 100.000 são expressos em um subconjunto do sistema de numeração indiano.

https://en.wikipedia.org/wiki/Indian_English#Numbering_system

Que significa:

1000000 units in pt-BR are formatted 1.000.000
1000000 units in en-US are formatted 1,000,000
1000000 units in en-IN are formatted 10,00,000

Além de vírgulas, pontos e outros separadores específicos, parece que o mascaramento também é uma preocupação válida.

Quais outras advertências devo estar atento ao localizar números no meu aplicativo front-end? Especialmente se eu estiver mostrando números para conjuntos de caracteres não latinos?


3
Fica ainda mais interessante ao lidar com dinheiro! :-)
Stephan Bijzitter

4
Sem falar no sistema de numeração marciana que tem a base 6 (duas vezes três dedos) ;-) Mas o japonês também tem uma estranheza: homem = 10.000 escrito como 1.0000, oku = 100.000.000 escrito no Japão como 1.0000.0000 e chō. .. palpite
qwerty_so 6/12/16

6
Por que você precisa se preocupar com isso? Você não consegue seguir as configurações do sistema operacional?
Jan Doggen

3
@JanDoggen, porque esse é um dos problemas interessantes do domínio de Engenharia de Software, "como apresentar adequadamente os dados às pessoas". O que eu deveria me preocupar ao projetar um sistema é o domínio dessa pergunta. E nem estou falando de dinheiro, como disse nosso amigo Stephan, nem de data e hora. Apenas números brutos.
Machado

5
@ JanDoggen, isso fica muito mais complexo quando se lida com software online. O usuário pode estar na Índia, em um computador em inglês dos EUA, mas lendo uma página da Web em português do Brasil. Seu servidor pode ser chinês. Seu aplicativo deve entender o que o usuário deseja, independentemente do SO que ele está usando ou de onde está o servidor. Assim, seus 1.000,00 dólares se tornam 67.545,00 rúpias: uma moeda dos EUA, convertida à taxa de câmbio local, mas exibida no formato em português.
Nodeman

Respostas:


87

A maioria das linguagens e estruturas de programação já possui um mecanismo de trabalho sensível que você pode usar para isso.

Por exemplo, o ecossistema C # possui o espaço para nome System.Globalization , que permite especificar o que Culturevocê deseja:

Console.WriteLine(myMoneyValue.ToString("C", "en-US"));

Isso não é algo que você deseja reinventar. Use os recursos de internacionalização fornecidos pelo seu idioma ou estrutura favorita.


2
Estou ciente do System.Globalization e outras estruturas que lidam com esse tipo de complexidade para mim. O que eu não sei é quais problemas eles estão resolvendo. Por exemplo, vários aplicativos que eu vejo usam mascaramento específico no ToString, como .ToString ("#, ## 0.00", locale), mas essa máscara em si é inválida se eu estiver exibindo esse número para uma pessoa indiana. Então, além de "não usar máscaras específicas", do que mais devo estar ciente?
Machado

7
Nada que eu saiba. Se você usar a estrutura corretamente, ela deverá funcionar. Existem certos casos específicos de problemas de internacionalização, mas criar uma lista abrangente deles não é algo que fazemos aqui. Veja este exemplo .
Robert Harvey

5
Esta é a única resposta correta: defina seu código de idioma e, em seguida, envie seus valores pela camada i18n antes de exibir para o usuário e deixe que os autores da estrutura lidem com ele. Isso vale para números, valores de moeda, cadeias traduzidas, datas, tudo.

2
Resposta perfeita. "Não reinvente a roda" é algo que sempre deve ser levado em consideração ao lidar com problemas comuns como este. É uma pena que eu não possa votar mais de uma vez.
BgrWorker

3
@Machado "Por exemplo, vários aplicativos que eu vejo usam mascaramento específico no ToString, como .ToString (" #, ## 0.00 ", locale), mas essa máscara em si é inválida se eu estiver exibindo esse número para uma pessoa indiana . " - Pode não estar claro, mas observe que a posição da ,string de formato é irrelevante e "#, 0,00" teria o mesmo efeito. ,significa simplesmente "use separadores de grupos de números da maneira especificada pelo código do idioma".
Hd

23

Algumas respostas excelentes já estão aqui, mas elas não mencionaram uma coisa que acho importante não esquecer: verifique onde quer que ocorra uma formatação de números, é claro (ou pode ser controlado) para que serve a saída:

  • quando for para a interface do usuário, a formatação localizada deve ser aplicada

  • quando o número for gravado em um arquivo ou enviado pela rede ou outra forma em que o número for necessário em formato legível por máquina , verifique se ele não está formatado de acordo com a cultura atual, mas de acordo com uma configuração fixa (por exemplo, no ambiente .NET, use InvariantCulture).

Caso contrário, você terá problemas quando os números são escritos ou enviados usando a cultura A e lidos ou recebidos usando a cultura B.

De acordo com a minha experiência, esse é um dos maiores obstáculos para a localização adequada de números: em uma tentativa de centralizar a formatação e conversão de números, as pessoas começam a criar funções gerais e reutilizáveis ​​para a formatação e, em seguida, começam a usá-las em todo o mundo. Lugar, colocar. No entanto, assim que você precisar dos números também em um formato de sequência legível por máquina em algum outro local do programa, são necessárias duas variantes: uma formatação localizada e uma não localizada. Isso apresenta um alto risco de misturar as duas formas de conversão (especialmente quando os desenvolvedores e as máquinas de teste têm suas configurações de localidade padrão semelhantes à configuração "fixa" usada para formatação sem interface do usuário, mas parte da base de usuários não possui).

Adendo: esse problema pode se tornar realmente desagradável em situações em que não está claro de antemão se o número será processado por uma máquina ou por um ser humano (ou ambos) posteriormente. Por exemplo, como parte da saída de um arquivo de log. Nesses casos, provavelmente é melhor seguir o padrão "neutro" de não usar separador, exceto o ponto como separador decimal.


2
E, pior ainda, em muitas linguagens de programação modernas, as funções óbvias / padrão na biblioteca padrão são "localizadas". Portanto, se o desenvolvedor não souber ou se preocupar com a localização, o aplicativo resultante provavelmente será disfuncional, e não apenas feio em sistemas externos.
Peter Green,

4
Eu discordo igualmente ruim. Uma ferramenta que não segue as convenções numéricas locais em sua interface do usuário ainda será útil. Uma ferramenta que falha ao ler seus próprios arquivos de dados ou falha ao conversar com seu servidor devido a incompatibilidades numéricas de convenções tem muito mais probabilidade de ser inutilizável.
Peter Green,

5
Uma anedota desta: O separador decimal para en-ZA mudou entre Win 7 e 8. Win valores previamente armazenados localmente começou a falhar em desserializar
Caleth

1
@PeterGreen: uma ferramenta que não segue as convenções numéricas locais nele de UI podem ainda ser utilizáveis, ou ele pode ser totalmente inutilizável para certos casos de uso. Eu teria muito cuidado em fazer tais suposições. A razão pela qual tantos desenvolvedores incorretamente localizam os números é exatamente isso - fazendo esse tipo de suposição.
Doc Brown

1
@DocBrown Eu tenho o código legado mais horrível de manter que sofre com as rotinas de análise de número inteiro / flutuação localizadas da biblioteca padrão. Eu acho que é justo dizer que um programa escrito sem cuidar da localização quando as rotinas padrão desses trabalhos não são localizados pode não ser utilizável em algumas situações, mas se as rotinas padrão forem localizadas, o programa sempre será interrompido no momento em que for executado em um computador em que o código do idioma global não seja inglês.
Sebastian Redl

9

A localização adequada é bastante difícil. A maioria dos ecossistemas de programação tem tentativas de encontrar soluções para localização, mas, na minha experiência, elas são todas mais ou menos quebradas. Eu sugeriria, portanto:

  • Não tente automatizar a localização. Nem sempre funciona. É difícil para você identificar os problemas e frustrante para seus usuários.

  • Seja consistente: não misture idiomas diferentes e convenções de formatação, por exemplo, separadores decimais no estilo brasileiro em texto em inglês.

  • Suporte explicitamente a um determinado conjunto de códigos de idioma. Trabalhe em conjunto com seus tradutores para descobrir a formatação adequada para datas e números. Você provavelmente criará seu próprio kit de ferramentas de localização, embora a maioria (mas não todos) dos problemas possa ser delegada a uma biblioteca existente.

  • Faça opções simples de formatação configuráveis ​​por cada usuário: formatos para datas e horas, separadores decimais, moeda preferida,…. Isso é especialmente útil para viajantes, expatriados ou outras pessoas que precisam misturar vários locais ou culturas independentemente do idioma.


18
Lembre-se também de que um grande número de usuários odeia a convenção considerada "correta para a localidade", considera-a uma prática hedionda de legado e não deseja nenhum agrupamento ou um tipo diferente de agrupamento. Como tal, provavelmente deve haver opções para desativá-lo ou substituí-lo manualmente.
R ..

2

Uma consideração importante: você deve decidir quanto é suficiente. Porque se você tentar encontrar na perfeição a toca do coelho, ficará cada vez mais complexo.

Escolha uma etiqueta típica como "Você selecionou n itens". Isso mostra errado se houver apenas um item selecionado. A solução feia, mas pragmática, é escrever "Você selecionou n item (s)". Mas se você quiser fazer isso corretamente, precisará de dois textos diferentes, dependendo do n. Se você tentar fazer isso em vários locais, ele rapidamente ficará realmente complexo, pois idiomas diferentes têm gramática diferente. Algumas línguas têm conjugações diferentes para um, dois e vários itens e assim por diante. Por esse motivo, as pessoas com conhecimento técnico sempre reclamam que as estruturas de localização existentes são insuficientes.

Mas você precisa escolher suas batalhas e decidir qual nível de sofisticação é suficiente. Para muitos propósitos, uma biblioteca de localização padrão para formatar números e datas deve ser suficiente.


Isso é resolvido pelo ICU (MessageFormat). A desvantagem é que a adoção da UTI em muitos idiomas ainda é fraca. No entanto, o desenvolvedor ainda precisa construir a mensagem da maneira certa. É realmente mais do que o aspecto de engenharia. userguide.icu-project.org/formatparse/messages
noderman

Isso também é resolvido pela função ngettext mais amplamente disponível no GNU gettext, mas a classe MessageFormat parece também resolver alguns problemas extras que o ngettext não resolve.
hvd

2

Você não pode estar ciente de todas as advertências de idiomas. Você está falando de números, mas existem plurais, gêneros, agrupamento. Você precisa saber que eles existem e contar com um extenso trabalho realizado por outras pessoas, principalmente os projetos de UTI e CLDR.

A maioria das linguagens modernas implementa alguns ou todos os recursos desses projetos, mas mesmo se não o fizerem, ler sobre esses projetos fornecerá uma boa idéia do que procurar.

http://site.icu-project.org

http://cldr.unicode.org

Atualizar

A ferramenta de pesquisa CLDR fornece acesso a todos os padrões. Isso mostrará como formatar um número em determinado idioma e região. Por exemplo, português (Portugal):

http://st.unicode.org/cldr-apps/v#/pt_PT/Number_Formatting_Patterns/

E se você realmente deseja verificar todos os dados (e talvez usá-los), pode fazer o download do CLDR no formato JSON do GitHub:

https://github.com/unicode-cldr/cldr-json#cldr-json

Mais informações sobre downloads aqui:

http://cldr.unicode.org/index/downloads


Obrigado pela contribuição, mas agora estou mais interessado em números. :)
Machado

Certo. Acabei de editar a resposta para incluir um link para a ferramenta de pesquisa, onde você pode restringir sua pesquisa.
Nodeman

Tentei mudar de Brasil, para verificar as diferenças, mas não parece permitir a visualização para isso: st.unicode.org/cldr-apps/v#/pt_BR/Number_Formatting_Patterns Caso contrário, a ferramenta parece muito boa.
Machado

Isso porque o Brasil é a língua raiz. A ferramenta de pesquisa é realmente usada para fazer alterações nos dados do CLDR, portanto, as raízes exigem contas especiais. Você pode acessar o GitHub e obter todas as informações diretamente: github.com/unicode-cldr/cldr-numbers-modern/tree/master/main Especificamente, o Brasil está aqui: github.com/unicode-cldr/cldr-numbers-modern/ blob / master / main / pt /…
noderman 08/12/16

0

Bem, enquanto estou feliz com todas as respostas aqui, não estou realmente satisfeito com cada uma delas separadamente para marcar uma como a resposta correta.

Até agora, é disso que devemos estar cientes ao localizar números:

Para humanos :

  • Milhares de separadores nem sempre estão se separando aos milhares. Veja caso indiano na pergunta;
  • Milhares e caracteres decimais variam de cultura para cultura. Em alemão, milhares são divididos usando espaços, por exemplo, enquanto em inglês são comuns e em português são pontos;
  • Não temos informações se houver uma diferença relevante entre os idiomas da esquerda para a direita e da direita para a esquerda;
  • Forneça um conjunto específico de localizações suportadas e deixe claro para seus usuários;
  • Permita que seus usuários alterem a localização padrão para uma das localizações suportadas e eles ficarão felizes e enviarão bolos agradecidos, porque você é um deus generoso. :);

Para computadores :

  • Lembre-se de que as máquinas não são tolerantes e sempre devem receber a mesma formatação ao serializar e desserializar um número;
  • Ficar com um único formato para ele;
  • Use o formato mínimo necessário possível. Para evitar a separação de milhares, os decimais devem ser suficientes para serialização e desserialização.

Para desenvolvedores :

  • (como sugerido por @hyde abaixo): use a biblioteca existente para localização;
  • Se puder, use testadores nativos e especifique casos de teste de localização / internacionalização; caso contrário, confie na biblioteca;
  • Lembre-se de que a localização é um problema principalmente resolvido. Todo idioma principal possui uma biblioteca, nativa ou externa, que pode localizar números, datas e horas;

1
Item ausente: para desenvolvedores: use a biblioteca existente para localização. Se puder, use testadores nativos e especifique casos de teste de localização / internacionalização; caso contrário, confie na biblioteca.
Hyde 8/12
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.