Is there a neat way of getting a Locale instance from its \"programmatic name\" as returned by Locale\'s toString()
method? An obvious and ugly solution would b
You can use this on Android. Works fine for me.
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;
}
Old question with plenty of answers, but here's more solutions:
See the Locale.getLanguage()
, Locale.getCountry()
... Store this combination in the database instead of the "programatic name"
...
When you want to build the Locale back, use public Locale(String language, String country)
Here is a sample 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);
}
Because I have just implemented it:
In Groovy
/Grails
it would be:
def locale = Locale.getAvailableLocales().find { availableLocale ->
return availableLocale.toString().equals(searchedLocale)
}
This answer may be a little late, but it turns out that parsing out the string is not as ugly as the OP assumed. I found it quite simple and concise:
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]);
}
I tested this (on Java 7) with all the examples given in the Locale.toString() documentation: "en", "de_DE", "_GB", "en_US_WIN", "de__POSIX", "zh_CN_#Hans", "zh_TW_#Hant-x-java", and "th_TH_TH_#u-nu-thai".
IMPORTANT UPDATE: This is not recommended for use in Java 7+ according to the documentation:
In particular, clients who parse the output of toString into language, country, and variant fields can continue to do so (although this is strongly discouraged), although the variant field will have additional information in it if script or extensions are present.
Use Locale.forLanguageTag and Locale.toLanguageTag instead, or if you must, Locale.Builder.
There doesn't seem to be a static valueOf
method for this, which is a bit surprising.
One rather ugly, but simple, way, would be to iterate over Locale.getAvailableLocales()
, comparing their toString
values with your value.
Not very nice, but no string parsing required. You could pre-populate a Map
of Strings to Locales, and look up your database string in that Map.