Existe-t-il un moyen astucieux d’obtenir une instance Locale à partir de son "nom de programme" renvoyée par la méthode toString()
de Locale? Une solution évidente et laide consisterait à analyser la chaîne, puis à créer une nouvelle instance de paramètres régionaux en fonction de cela, mais peut-être qu'il existe une meilleure solution/solution prête pour cela?
Le besoin est que je veuille stocker certains paramètres spécifiques à une locale dans une base de données SQL, y compris les locales, mais il serait déplaisant d'y placer des objets localisés sérialisés. Je préférerais stocker leurs représentations String, qui semblent être tout à fait adéquates en détail.
Voir le Locale.getLanguage()
, Locale.getCountry()
... Stockez cette combinaison dans la base de données à la place du "programatic name"
...
Lorsque vous souhaitez reconstituer les paramètres régionaux, utilisez public Locale(String language, String country)
Voici un exemple de code :)
// May contain simple syntax error, I don't have Java right now to test..
// but this is a bigger picture for your algo...
public String localeToString(Locale l) {
return l.getLanguage() + "," + l.getCountry();
}
public Locale stringToLocale(String s) {
StringTokenizer tempStringTokenizer = new StringTokenizer(s,",");
if(tempStringTokenizer.hasMoreTokens())
String l = tempStringTokenizer.nextElement();
if(tempStringTokenizer.hasMoreTokens())
String c = tempStringTokenizer.nextElement();
return new Locale(l,c);
}
La méthode qui retourne les paramètres régionaux de la chaîne existe dans la bibliothèque commons-lang: LocaleUtils.toLocale(localeAsString)
Depuis Java 7, il existe une méthode de fabrique Locale.forLanguageTag
et méthode d'instance Locale.toLanguageTag
utilisant balises de langue IETF .
Java fournit beaucoup de choses avec une implémentation correcte, beaucoup de complexité peut être évitée. Ceci retourne ms_MY .
String key = "ms-MY";
Locale locale = new Locale.Builder().setLanguageTag(key).build();
Apache Commons a LocaleUtils
pour aider à analyser une représentation de chaîne. Cela retournera en_US
String str = "en-US";
Locale locale = LocaleUtils.toLocale(str);
System.out.println(locale.toString());
Vous pouvez également utiliser des constructeurs de paramètres régionaux.
// Construct a locale from a language code.(eg: en)
new Locale(String language)
// Construct a locale from language and country.(eg: en and US)
new Locale(String language, String country)
// Construct a locale from language, country and variant.
new Locale(String language, String country, String variant)
Veuillez vérifier ceci LocaleUtils et ceci Locale pour explorer plus de méthodes.
Option 1:
org.Apache.commons.lang3.LocaleUtils.toLocale("en_US")
Option 2:
Locale.forLanguageTag("en-US")
Veuillez noter que Option 1 est un "trait de soulignement" entre la langue et le pays et Option 2 est un "tiret".
Cette réponse est peut-être un peu tardive, mais il s'avère que l'analyse de la chaîne n'est pas aussi laide que le supposait le PO. Je l'ai trouvé assez simple et concis:
public static Locale fromString(String locale) {
String parts[] = locale.split("_", -1);
if (parts.length == 1) return new Locale(parts[0]);
else if (parts.length == 2
|| (parts.length == 3 && parts[2].startsWith("#")))
return new Locale(parts[0], parts[1]);
else return new Locale(parts[0], parts[1], parts[2]);
}
J'ai testé cela (on Java 7) avec tous les exemples donnés dans la documentation de Locale.toString (): "en", "de_DE", "_GB", "en_US_WIN", "de__POSIX" , "zh_CN_ # Hans", "zh_TW_ # Hant-x-Java" et "th_TH_TH_ # u-nu-thai".
IMPORTANT UPDATE : son utilisation est déconseillée dans Java 7+ selon le documentation =:
En particulier, les clients qui analysent la sortie de toString dans les champs language, country et variant peuvent continuer à le faire (bien que cela soit fortement déconseillé ), bien que le champ variant contiendra des informations supplémentaires si un script ou des extensions sont présents.
Utilisez Locale.forLanguageTag et Locale.toLanguageTag à la place, ou si vous devez, Locale.Builder.
Ancienne question avec beaucoup de réponses, mais voici d'autres solutions:
Si vous utilisez le framework Spring dans votre projet, vous pouvez également utiliser:
org.springframework.util.StringUtils.parseLocaleString("en_US");
Analyser la représentation de chaîne donnée dans un paramètre régional
Vous pouvez l'utiliser sur Android. Fonctionne bien pour moi.
private static final Pattern localeMatcher = Pattern.compile
("^([^_]*)(_([^_]*)(_#(.*))?)?$");
public static Locale parseLocale(String value) {
Matcher matcher = localeMatcher.matcher(value.replace('-', '_'));
return matcher.find()
? TextUtils.isEmpty(matcher.group(5))
? TextUtils.isEmpty(matcher.group(3))
? TextUtils.isEmpty(matcher.group(1))
? null
: new Locale(matcher.group(1))
: new Locale(matcher.group(1), matcher.group(3))
: new Locale(matcher.group(1), matcher.group(3),
matcher.group(5))
: null;
}
Il ne semble pas y avoir de méthode statique valueOf
pour cela, ce qui est un peu surprenant.
Une façon plutôt laide, mais simple, serait de parcourir Locale.getAvailableLocales()
, en comparant leurs valeurs toString
à votre valeur.
Pas très gentil, mais aucune analyse de chaîne n'est requise. Vous pouvez pré-renseigner un Map
de chaînes de caractères vers des locales et rechercher votre chaîne de base de données dans cette carte.
Parce que je viens de l'implémenter:
Dans Groovy
/Grails
ce serait:
def locale = Locale.getAvailableLocales().find { availableLocale ->
return availableLocale.toString().equals(searchedLocale)
}
Eh bien, je stockerais plutôt une concaténation de chaîne de Locale.getISO3Language()
, getISO3Country()
et getVariant () comme clé, ce qui me permettrait d'appeler plus tard Locale(String language, String country, String variant)
constructeur.
en effet, l'utilisation de displayLanguage implique l'utilisation du langage de la locale pour l'afficher, ce qui la rend dépendante de la locale, contrairement au code de langue iso.
Par exemple, la clé en locale serait stockable de la manière suivante:
en_EN
en_US
etc ...