¿Cómo localizar adecuadamente los números?

38

¿Qué advertencias debo tener en cuenta al localizar números en mi aplicación front-end?

Ejemplo: en portugués brasileño (pt-BR) dividimos miles con puntos y decimales con comas. En inglés de EE. UU. (En-EE. UU.) Eso es lo contrario. En pt-BR presentamos los dígitos separados por miles, lo mismo que en-US. Pero al leer sobre el inglés indio (en-IN) hoy me encontré con esta joya:

Se prefiere el sistema de numeración indio para la agrupación de dígitos. Cuando se escribe en palabras, o cuando se habla, los números de menos de 100,000 / 100,000 se expresan tal como están en inglés estándar. Los números que incluyen más allá de 100,000 / 100,000 se expresan en un subconjunto del sistema de numeración indio.

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

Lo 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

Además de comas y puntos y otros separadores específicos, parece que el enmascaramiento también es una preocupación válida.

¿Qué otras advertencias debo tener en cuenta al localizar números en mi aplicación front-end? ¿Especialmente si estoy mostrando números a conjuntos de caracteres no latinos?

Machado
fuente
3
¡Se vuelve aún más interesante cuando se trata de dinero! :-)
Stephan Bijzitter
44
No hablamos del sistema de numeración marciano que tiene la base 6 (dos veces 3 dedos) ;-) Pero el japonés también tiene una extrañeza: hombre = 10.000 escrito como 1.0000, oku = 100.000.000 escrito en Japón como 1.0000.0000 y chō. .. adivina
qwerty_so
66
¿Por qué tienes que preocuparte por esto? ¿No puedes seguir la configuración del sistema operativo?
Jan Doggen
3
@ JanDoggen porque ese es uno de los problemas interesantes del dominio de Ingeniería de Software, "cómo presentar los datos adecuadamente a las personas". Lo que debería preocuparme al diseñar un sistema es el dominio de esta pregunta. Y ni siquiera estoy hablando de dinero, como dijo nuestro amigo Stephan, ni de la fecha y la hora. Solo números en bruto.
Machado
55
@ JanDoggen, esto se vuelve mucho más complejo cuando se trata de software en línea. El usuario puede estar en la India, en una computadora en inglés de EE. UU., Pero leyendo una página web en portugués de Brasil. Su servidor puede ser chino. Su aplicación debe comprender lo que quiere el usuario, independientemente de qué sistema operativo esté utilizando o dónde se encuentre su servidor. Entonces sus 1,000.00 dólares se convierten en 67.545,00 rupias: una moneda estadounidense, convertida al tipo de cambio local, pero mostrada en formato portugués.
noderman

Respuestas:

87

La mayoría de los lenguajes y marcos de programación ya tienen un mecanismo de trabajo sensible que puede usar para esto.

Por ejemplo, el ecosistema C # tiene el espacio de nombres System.Globalization , que le permite especificar lo Cultureque desea:

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

Esto no es algo que quieras reinventar. Use las funciones de internacionalización proporcionadas por su idioma o marco favorito.

Robert Harvey
fuente
2
Soy consciente de System.Globalization y otros marcos que manejan este tipo de complejidad para mí. Lo que no sé es qué problemas están resolviendo. Por ejemplo, varias aplicaciones que veo usan un enmascaramiento específico en ToString, como .ToString ("#, ## 0.00", locale), pero esa máscara per-se no es válida si le estoy mostrando este número a una persona india. Entonces, además de "no usar máscaras específicas", ¿qué más debo tener en cuenta?
Machado
77
Nada que yo sepa. Si usa el marco correctamente, debería funcionar. Hay ciertos casos específicos de problemas de internacionalización, pero construir una lista completa de ellos no es algo que hagamos aquí. Ver este ejemplo .
Robert Harvey
55
Esta es la única respuesta correcta: establezca su configuración regional, luego empuje sus valores a través de la capa i18n antes de mostrar al usuario y deje que los autores del marco se encarguen de ello. Esto es cierto para números, valores de moneda, cadenas traducidas, fechas, todo.
2
Respuesta perfecta. "No reinventar la rueda" es algo que siempre debe tenerse en cuenta al tratar problemas comunes como este. Es una pena que no pueda votar más de una vez.
BgrWorker
3
@Machado "Por ejemplo, varias aplicaciones que veo usan un enmascaramiento específico en ToString, como .ToString (" #, ## 0.00 ", locale), pero esa máscara per-se no es válida si le estoy mostrando este número a una persona india ". - Puede que no esté claro, pero tenga en cuenta que la posición de ,en la cadena de formato es en gran medida irrelevante y "#, 0.00" tendría el mismo efecto. ,simplemente significa "usar separadores de grupos de números de la manera especificada por la configuración regional".
hvd
23

Algunas respuestas excelentes aquí ya, pero no mencionaron una cosa que creo que es importante no olvidar: asegúrese de que donde sea que tenga lugar un formateo de números, esté claro (o se pueda controlar) para qué se utiliza la salida:

  • cuando se trata de la interfaz de usuario, se debe aplicar el formato localizado

  • cuando el número se escribirá en un archivo, o se enviará a través de la red, u otra forma en la que se necesita el número en forma legible por máquina , asegúrese de que no esté formateado de acuerdo con la cultura actual, sino de acuerdo con una configuración fija (por ejemplo, en el entorno .NET, use InvariantCulture).

De lo contrario, tiene problemas cuando los números se escriben o envían utilizando la cultura A, y se leen o reciben utilizando la cultura B.

Según mi experiencia, este es uno de los mayores obstáculos para hacer una localización adecuada de los números: en un intento de centralizar el formato y la conversión de números, las personas comienzan a crear funciones generales y reutilizables para el formateo, y luego comienzan a usarlas en todo el lugar. Sin embargo, tan pronto como uno necesite los números también en un formato de cadena legible por máquina en otro lugar del programa, se necesitan dos variantes: un formato localizado y otro no localizado. Esto introduce un alto riesgo de mezclar las dos formas de conversiones (especialmente cuando los desarrolladores y las máquinas de prueba tienen su configuración regional predeterminada similar a la configuración "fija" utilizada para el formateo sin UI, pero parte de la base de usuarios no la tiene).

Anexo: este problema puede volverse realmente desagradable en situaciones en las que no está claro de antemano si el número será procesado por una máquina o por un humano (o ambos) más adelante. Por ejemplo, como parte de la salida de un archivo de registro. En tales casos, probablemente sea mejor atenerse al estándar "neutral" de no usar ningún separador excepto el punto como separador decimal.

Doc Brown
fuente
2
Y lo que es peor, en muchos lenguajes modernos de programación, las funciones obvias / predeterminadas en la biblioteca estándar están "localizadas". Entonces, si el desarrollador no sabe o no le importa la localización, es probable que la aplicación resultante sea disfuncional en lugar de simplemente fea en sistemas extranjeros.
Peter Green
44
No estoy de acuerdo en igual de malo. Una herramienta que no sigue las convenciones numéricas locales en su interfaz de usuario seguirá siendo utilizable. Una herramienta que no puede leer sus propios archivos de datos o no puede comunicarse con su servidor debido a los desajustes de las convenciones numéricas es mucho más probable que sea inutilizable.
Peter Green
55
Una anécdota de esto: el separador decimal para en-ZA cambió entre Win 7 y Win 8. Los valores almacenados localmente anteriormente comenzaron a fallar en la deserialización
Caleth
1
@PeterGreen: una herramienta que no sigue las convenciones numéricas locales en su interfaz de usuario aún puede ser utilizable, o puede ser completamente inutilizable para ciertos casos de uso. Tendría mucho cuidado de hacer tales suposiciones. La razón por la que tantos desarrolladores se equivocan en la localización de los números es exactamente eso: hacer este tipo de suposiciones.
Doc Brown
1
@DocBrown Tengo que mantener el código heredado más horrible que sufre de las rutinas de análisis de números enteros / flotantes localizados de la biblioteca estándar. Creo que es justo decir que un programa escrito sin cuidado para la localización cuando las rutinas predeterminadas para estos trabajos no están localizadas puede ser inutilizable para algunas situaciones, pero si las rutinas predeterminadas están localizadas, el programa siempre se interrumpirá en el momento en que sea ejecutado en una computadora donde la localización global no es inglesa.
Sebastian Redl
9

La localización adecuada es bastante difícil. La mayoría de los ecosistemas de programación tienen intentos de encontrar soluciones para la localización, pero en mi experiencia están todos más o menos rotos. Por lo tanto, sugeriría:

  • No intentes automatizar la localización. No siempre funcionará. Es difícil detectar los problemas y frustrante para los usuarios.

  • Sea coherente: no mezcle diferentes idiomas y convenciones de formato, por ejemplo, separadores decimales de estilo brasileño en texto en inglés.

  • Admite explícitamente un conjunto dado de configuraciones regionales. Trabaje junto con sus traductores para determinar el formato adecuado para fechas y números. Probablemente terminará creando su propio kit de herramientas de localización, aunque la mayoría (pero no todos) los problemas pueden delegarse en una biblioteca existente.

  • Haga elecciones de formato simples configurables por cada usuario: formatos para fechas y horas, separadores decimales, moneda preferida, ... Esto es especialmente útil para viajeros, expatriados u otras personas que necesitan mezclar múltiples lugares o culturas independientemente del idioma.

amon
fuente
18
También tenga en cuenta que una gran cantidad de usuarios odian la convención que se considera "correcta para su ubicación", la consideran una práctica heredada horrible y no quieren agruparse en absoluto, o un tipo diferente de agrupación. Como tal, probablemente debería haber opciones para apagarlo o anularlo manualmente.
R ..
2

Una consideración importante: debe decidir cuánto es suficiente. Porque si te pasas por la madriguera del conejo tratando de localizarlo perfectamente, se volverá cada vez más complejo.

Tome una etiqueta típica como "Ha seleccionado n elementos". Esto se lee mal si solo hay un elemento seleccionado. La solución fea pero pragmática es escribir "Ha seleccionado n elemento (s)". Pero si quieres hacerlo correctamente, necesitas dos textos diferentes dependiendo de n. Si intenta hacer esto en varias configuraciones regionales, rápidamente se volverá realmente complejo, ya que los diferentes idiomas tienen una gramática diferente. Algunos idiomas tienen diferentes conjugaciones para uno, dos y múltiples elementos, etc. Por este motivo, las personas con conocimiento siempre se quejarán de que los marcos de localización existentes son insuficientes.

Pero tienes que elegir tus batallas y decidir qué nivel de sofisticación es suficiente. Para muchos propósitos, una biblioteca de localización estándar para formatear números y fechas debería ser suficiente.

JacquesB
fuente
Esto es resuelto por ICU (MessageFormat). El inconveniente es que la adopción de la UCI en muchos idiomas sigue siendo débil. Sin embargo, el desarrollador aún necesita construir el mensaje de la manera correcta. Realmente es más que el aspecto de ingeniería. userguide.icu-project.org/formatparse/messages
noderman
Esto también se resuelve con la función ngettext más ampliamente disponible en GNU gettext, pero la clase MessageFormat también parece resolver algunos problemas adicionales que ngettext no soluciona.
hvd
2

No puedes estar al tanto de todas las advertencias de los idiomas. Estás hablando de números, pero hay plurales, géneros, colación. Debe saber que existen y confiar en el extenso trabajo realizado por otras personas, especialmente los proyectos de UCI y CLDR.

La mayoría de los lenguajes modernos implementan algunas o todas las características de estos proyectos, pero incluso si no lo hacen, leer sobre estos proyectos le dará una buena idea de qué buscar.

http://site.icu-project.org

http://cldr.unicode.org

Actualizar

La herramienta de encuesta CLDR proporciona acceso a todos los patrones. Eso le mostrará cómo formatear un número en cierto idioma y región. Por ejemplo, portugués (Portugal):

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

Y si realmente desea verificar todos los datos (y tal vez usarlos), puede descargar el CLDR en formato JSON desde GitHub:

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

Más información sobre descargas aquí:

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

noderman
fuente
Gracias por el aporte, pero ahora estoy más interesado en los números. :)
Machado
Seguro. Acabo de editar la respuesta para incluir un enlace a la herramienta de encuesta, donde puede limitar su búsqueda.
noderman
Traté de cambiar do Brazil, para verificar las diferencias, pero no parece permitir la visualización para eso: st.unicode.org/cldr-apps/v#/pt_BR/Number_Formatting_Patterns De lo contrario, la herramienta parece bastante buena.
Machado
Eso es porque Brasil es el idioma raíz. La herramienta de encuesta se utiliza para realizar cambios en los datos CLDR, por lo que las raíces requieren cuentas especiales. Puede ir a GitHub y obtener toda la información directamente: github.com/unicode-cldr/cldr-numbers-modern/tree/master/main Específicamente, Brasil está aquí: github.com/unicode-cldr/cldr-numbers-modern/ blob / master / main / pt / ...
noderman
0

Bueno, aunque estoy contento con todas las respuestas aquí, no estoy realmente satisfecho con cada una de ellas por separado para marcar una como la respuesta correcta.

Hasta ahora, esto es lo que debemos tener en cuenta al localizar números:

Para humanos :

  • Miles de separadores no siempre se separan en miles. Ver caso indio en la pregunta;
  • Los caracteres de miles y decimales varían de cultura a cultura. En alemán, miles se dividen utilizando espacios, por ejemplo, mientras que en inglés son comas y en portugués son puntos;
  • No tenemos información si hay una diferencia relevante entre los idiomas de izquierda a derecha y de derecha a izquierda;
  • Proporcione un conjunto específico de localizaciones compatibles y deje en claro para sus usuarios;
  • Permita que sus usuarios cambien la localización predeterminada a una de las localizaciones compatibles y estarán felices y le enviarán pasteles agradecidos, porque es un dios generoso. :);

Para computadoras :

  • Recuerde que las máquinas no son indulgentes y siempre deben recibir el mismo formato al serializar y deserializar un número;
  • Quédese con un solo formato para ello;
  • Use el formato mínimo necesario posible. Evite la separación de miles, los decimales deberían ser suficientes para la serialización y la deserialización.

Para desarrolladores :

  • (como sugiere @hyde a continuación): Use la biblioteca existente para la localización;
  • Si puede, use probadores nativos y especifique casos de prueba de localización / internacionalización, de lo contrario confíe en la biblioteca;
  • Recuerde que la localización es un problema mayormente resuelto. Cada idioma principal tiene una biblioteca, nativa o externa, que puede localizar números, fechas y horas;
Machado
fuente
1
Elemento faltante: Para desarrolladores: use la biblioteca existente para la localización. Si puede, use probadores nativos y especifique casos de prueba de localización / internacionalización, de lo contrario confíe en la biblioteca.
hyde