Pergunta

Uma das partes divertidas da programação multicultural são os formatos numéricos.

  • Os americanos usam 10.000,50
  • Alemães usam 10.000,50
  • Francês usa 10 000,50

Minha primeira abordagem seria pegar a string, analisá-la de trás para frente até encontrar um separador e usá-lo como meu separador decimal.Há uma falha óbvia nisso:10.000 seriam interpretados como 10.

Outra abordagem:se a string contiver 2 caracteres não numéricos diferentes, use o último como separador decimal e descarte os demais.Se eu tiver apenas um, verifique se ocorre mais de uma vez e descarte-o se ocorrer.Se aparecer apenas uma vez, verifique se possui 3 dígitos depois.Se sim, descarte-o, caso contrário, use-o como separador decimal.

A "melhor solução" óbvia seria detectar a cultura ou navegador do usuário, mas isso não funciona se você tiver um francês usando um Windows/navegador en-US.

O .net Framework contém algum analisador mítico de ponto flutuante de magia negra que é melhor que Double.(Try)Parse() ao tentar detectar automaticamente o formato do número?

Foi útil?

Solução

Acho que o melhor que você pode fazer neste caso é aceitar a opinião deles e depois mostrar o que você acha que eles quiseram dizer.Se eles discordarem, mostre-lhes o formato que você espera e peça-lhes que o insiram novamente.

Outras dicas

Não conheço o lado ASP.NET do problema, mas o .NET tem uma classe bastante poderosa: System.Globalization.CultureInfo.Você pode usar o seguinte código para analisar uma string contendo um valor duplo:

double d = double.Parse("100.20", CultureInfo.CurrentCulture);
//  -- OR --
double d = double.Parse("100.20", CultureInfo.CurrentUICulture);

Se o ASP.NET de alguma forma (ou seja,usando cabeçalhos de solicitação HTTP) passa CultureInfo do usuário atual para CultureInfo.CurrentCulture ou CultureInfo.CurrentUICulture, eles funcionarão bem.

Você não pode agradar a todos.Se eu inserir dez como 10.000 e alguém inserir dez mil como 10.000, você não conseguirá lidar com isso sem algum conhecimento da cultura do insumo.Detecte a cultura de alguma forma (navegador, configuração do sistema - qual é o caso de uso?ASP?Aplicativo interno ou aberto ao mundo?), ou forneça um exemplo da formatação esperada e use o analisador mais tolerante possível.Provavelmente algo como:

double d = Double.Parse("5,000.00", NumberStyles.Any, CultureInfo.InvariantCulture);

A diferença entre 12,345 em francês e inglês é um fator de 1000.Se você fornecer um intervalo esperado onde max <1000*min, poderá adivinhar facilmente.

Tomemos por exemplo a altura de uma pessoa (incluindo bebés e crianças) em mm.

Ao usar um intervalo de 200 a 3.000, uma entrada de 1.800 ou 1.800 pode ser interpretada inequivocamente como 1 metro e 80 centímetros, enquanto uma entrada de 912.300 ou 912.300 pode ser interpretada inequivocamente como 91 centímetros e 2,3 milímetros.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top