thousands patterns pattern numberformat number example custom java internationalization currency

patterns - java numberformat custom format



Internacionalización del nombre de visualización de la moneda de Java (1)

Proveedores de servicios locales

Java usa un mecanismo extensible para proporcionar datos (como cadenas, formateadores, etc.) que están localizados.

Las clases pueden implementar LocaleServiceProvider para que sea una fábrica de datos sensibles locales. Muchas clases en java.util y java.text dependen de estos proveedores para que funcionen correctamente con una java.text Locale diferente al delegar la creación de objetos para ellos.

Puede encontrar ejemplos de proveedores de servicios locales en el paquete java.util.spi , que generalmente se usan para mostrar texto o números de una manera que depende de la configuración regional. Incluye CurrencyNameProvider que usa Currency al llamar a Currency#getDisplayName .

Encontrar implementaciones

Las clases que deseen utilizar un LocaleServiceProvider específico (como CurrencyNamePovider ) utilizan LocaleServiceProviderPool para buscar las instancias del proveedor que admiten una LocaleServiceProviderPool regional específica.

LocaleServiceProviderPool intenta primero usar una implementación predeterminada incluida en el JRE . Si no se encuentra, se basa en el mecanismo simple de interfaz de proveedor de servicios (SPI) en Java y utiliza un ServiceLoader 1 para tratar de encontrar implementaciones proporcionadas por bibliotecas de terceros .

Esto es lo que está escrito en el tutorial sobre Locale :

Estos métodos primero comprueban si el entorno de tiempo de ejecución de Java admite la configuración regional solicitada; si es así, usan ese apoyo. De lo contrario, los métodos llaman a los métodos getAvailableLocales () de los proveedores instalados para que la interfaz adecuada encuentre un proveedor que admita la configuración regional solicitada.

Las implementaciones predeterminadas de los proveedores que vienen con JRE se pueden encontrar en el paquete sun.util.locale.provider . Es complejo, pero básicamente obtiene los datos del localedata.jar jar localedata.jar . En Oracle JDK, se encuentra en java_home/jre/lib/ext/localedata.jar . Si enumera los archivos que están en este jar y revisa los archivos en sun.util.resources.es y en sun.util.resources.ru , verá que hay muchos más nombres de moneda definidos para español que para ruso.

Estos son los archivos de OpenJDK: ruso vs español .

¿Qué pasa si no está definido en absoluto?

Los entornos locales están organizados en una jerarquía. Por ejemplo, una región específica de un país puede tener una configuración regional que refleje algunas diferencias locales de la configuración regional del país. Si no se encuentran datos para una LocaleServiceProviderPool regional, LocaleServiceProviderPool intentará utilizar el elemento principal de la LocaleServiceProviderPool regional.

La raíz del árbol de configuraciones regionales es básicamente una configuración regional ficticia alternativa que proporciona valores predeterminados para todos los datos localizados.

Eso es lo que probablemente sucede cuando solicitas el nombre para mostrar de USD en ruso.

Extensibilidad

Cualquier programa puede proporcionar información de configuración regional adicional. Deben definir un proveedor de servicios 1 creando el archivo de metadatos e implementando un CurrencyNameProvider . Puede completar los datos localizados faltantes en su propio contenedor.

Conclusión

¿O Java no ha logrado traducirlo?

Eso es más o menos el caso.

¿O estoy haciendo algo incorrectamente?

No, puede confiar en los valores predeterminados o proporcionar los datos localizados usted mismo.

1 El ServiceLoader los encontrará pidiéndole al cargador de clases que cargue el recurso META-INF/services/java.text.spi.DateFormatProvider . Si se encuentra dicho archivo, debe tener el nombre de clase específico de la implementación. Luego intenta crear una instancia a través del cargador de clases.

¿Hay alguna razón por la cual ciertos nombres para mostrar se muestran en inglés a pesar de que las configuraciones regionales no están en inglés (es decir, no traducidas).

Por ejemplo: Locale: "ru" no está traducido

Locale locale = new Locale("ru"); Currency curr = Currency.getInstance("USD"); System.out.println(curr.getDisplayName(locale)); // US Dollar

Locale: "es" está traducido

Locale locale = new Locale("es"); Currency curr = Currency.getInstance("USD"); System.out.println(curr.getDisplayName(locale)); // dólar estadounidense

Es esto intencional? ¿O Java no ha logrado traducirlo? ¿O estoy haciendo algo incorrectamente?

Traté de localizar los archivos donde están almacenadas estas traducciones pero no pude encontrarlas. Si alguien pudiera señalarme ese recurso también sería útil.

Gracias.