8

My app is being fed string from an external process, where each string is either 2- or 5-characters in length, and represents a java.util.Locales. For example:

en-us

ko

The first example is a 5-char string where "en" is the ISO language code, and "us" is the ISO country code. This should correspond to the "en_US" Locale. The second example is only a 2-char string, where "ko" is the ISO language code, and should correspond to the "ko_KR" (Korean) Locale.

I need a way to take these strings (either the 2- or 5-char variety), validate it (as a supported Java 6 Locale), and then create a Locale instance with it.

I would have hoped that Locale came with such validation out of the box, but unfortunately this code runs without exceptions being thrown:

Locale loc = new Locale("waawaaweewah", "greatsuccess");

// Prints: "waawaaweewah"
System.out.println(loc.getDisplayLanguage());

So I ask, given me the 2 forms that these string will be given to me in, how can I:

  • Validate the string (both forms) and throw an exception for strings corresponding to non-existent or unsupported Java 6 Locales; and
  • Instantiate a new Locale from the string? This question really applies to the 2-char form, where I might only have "ko" and need it to map to the "ko_KR" Locale, etc.

Thanks in advance!

4

2 回答 2

8

Locale.getISOCountries() and Locale.getISOLanguages()

return a list of all 2-letter country and language codes defined in ISO 3166 and ISO 639 respectively and can be used to create Locales.

You can use this to validate your inputs.

于 2013-03-27T16:09:12.470 回答
3

You have two options,

  1. Use a library for doing this commons-lang has the LocaleUtils class that has a method that can parse a String to a Locale.
  2. While your own method, the validation here is non trivial as there are a number of different sets of country codes that a valid for a Locale - see the javadoc

A starting point would be to split the String and switch on the number of elements:

public static Locale parseLocale(final String locale) {
    final String[] localeArr = locale.split("_");
    switch (localeArr.length) {
        case 1:
            return new Locale(localeArr[0]);
        case 2:
            return new Locale(localeArr[0], localeArr[1]);
        case 3:
            return new Locale(localeArr[0], localeArr[1], localeArr[2]);
        default:
            throw new IllegalArgumentException("Invalid locale format;");
    }
}

Presumably you would need to get lists of all valid country codes and languages and compare the elements in the String[] to the valid values before calling the constructor.

于 2013-03-27T16:15:15.160 回答