How to get Locale from its String representation in Java?

JavaLocale

Java Problem Overview


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 be parsing the String and then constructing a new Locale instance according to that, but maybe there's a better way / ready solution for that?

The need is that I want to store some locale specific settings in a SQL database, including Locales themselves, but it would be ugly to put serialized Locale objects there. I would rather store their String representations, which seem to be quite adequate in detail.

Java Solutions


Solution 1 - Java

Method that returns locale from string exists in commons-lang library: LocaleUtils.toLocale(localeAsString)

Solution 2 - Java

Since Java 7 there is factory method Locale.forLanguageTag and instance method Locale.toLanguageTag using IETF language tags.

Solution 3 - Java

  1. Java provides lot of things with proper implementation lot of complexity can be avoided. This returns ms_MY.

    String key = "ms-MY";
    Locale locale = new Locale.Builder().setLanguageTag(key).build();
    
  2. Apache Commons has LocaleUtils to help parse a string representation. This will return en_US

     String str = "en-US";
     Locale locale =  LocaleUtils.toLocale(str);
     System.out.println(locale.toString());
    
  3. You can also use locale constructors.

     // 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)
    

Please check this LocaleUtils and this Locale to explore more methods.

Solution 4 - Java

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);
}

Solution 5 - Java

Option 1 :

org.apache.commons.lang3.LocaleUtils.toLocale("en_US")

Option 2 :

Locale.forLanguageTag("en-US")

Please note Option 1 is "underscore" between language and country , and Option 2 is "dash".

Solution 6 - Java

If you are using Spring framework in your project you can also use:

org.springframework.util.StringUtils.parseLocaleString("en_US");

Documentation:

> Parse the given String representation into a Locale

Solution 7 - Java

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.

Solution 8 - Java

Old question with plenty of answers, but here's more solutions:

Solution 9 - Java

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.

Solution 10 - Java

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;
}

Solution 11 - Java

Well, I would store instead a string concatenation of Locale.getISO3Language(), getISO3Country() and getVariant() as key, which would allow me to latter call Locale(String language, String country, String variant) constructor.

indeed, relying of displayLanguage implies using the langage of locale to display it, which make it locale dependant, contrary to iso language code.

As an example, en locale key would be storable as

en_EN
en_US

and so on ...

Solution 12 - Java

Because I have just implemented it:

In Groovy/Grails it would be:

def locale = Locale.getAvailableLocales().find { availableLocale ->
      return availableLocale.toString().equals(searchedLocale)
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJoonas PulakkaView Question on Stackoverflow
Solution 1 - JavayuriloView Answer on Stackoverflow
Solution 2 - JavanilskpView Answer on Stackoverflow
Solution 3 - JavaVeKeView Answer on Stackoverflow
Solution 4 - JavarajView Answer on Stackoverflow
Solution 5 - JavajunjunView Answer on Stackoverflow
Solution 6 - JavaJavad AlimohammadiView Answer on Stackoverflow
Solution 7 - JavaandyView Answer on Stackoverflow
Solution 8 - JavaTaurenView Answer on Stackoverflow
Solution 9 - JavaskaffmanView Answer on Stackoverflow
Solution 10 - JavaMygodView Answer on Stackoverflow
Solution 11 - JavaRiduidelView Answer on Stackoverflow
Solution 12 - JavaMartin L.View Answer on Stackoverflow