How can I create a Locale with a specific script code?

Viewed 835

I'm trying to convert this String az_AZ_#Latn, found here, to a Locale but I'm unable to parse the #Latn part.

If I do new Locale("az_AZ_#Latn") I lose the #Latn part (the Script code).

I've tried as well using the LocaleUtils from commons-lang but I get an error saying that it's an invalid format.

4 Answers

As written in the docs:

It is not possible to set a script code on a Locale object in a release earlier than JDK 7.

But you can use the Locale builder to make it like this:

Locale locale = new Locale.Builder().setLanguage("az").setRegion("AZ").setScript("Latn").build();

You can get the Script it by calling locale.getScript()

Edit:

Here's a method I made for converting a string into a locale (doesn't work for extensions):

public static Locale stringToLocale(String locale){
    if(locale == null || locale.isEmpty()) return null;
    String[] parts = locale.split("_");
    if(parts.length == 1) return new Locale(parts[0]);
    if(parts.length == 2) return new Locale(parts[0],parts[1]);
    if(parts.length == 3) 
        if(parts[2].charAt(0) != '#') return new Locale(parts[0],parts[1],parts[2]);
        else return new Locale.Builder().setLanguage(parts[0]).setRegion(parts[1]).setScript(parts[2].substring(1)).build();
    if(parts.length == 4) return new Locale.Builder().setLanguage(parts[0]).setRegion(parts[1]).setVariant(parts[2]).setScript(parts[3].charAt(0)=='#'? parts[3].substring(1):null).build();
    return null;
}
    //works for the toString output expect for extensions. test: for(Locale l:  Locale.getAvailableLocales()) System.out.println(l.equals(stringToLocale(l.toString())));
   // output : true true true...

usage:

Locale l = stringToLocale("az_AZ_#Latn");

That #Latn refers to the script which in this case is Latin.

From java documentation:

script ISO 15924 alpha-4 script code. You can find a full list of valid script codes in the IANA Language Subtag Registry (search for "Type: script"). The script field is case insensitive, but Locale always canonicalizes to title case (the first letter is upper case and the rest of the letters are lower case). Well-formed script values have the form [a-zA-Z]{4} Example: "Latn" (Latin), "Cyrl" (Cyrillic)

If you want to create a Locale using the script you can use its builder.

For instance:

Locale locale = new Locale.Builder()
                    .setLanguage("az")
                    .setRegion("AZ")
                    .setScript("Latn")
                    .build();

Locale.Builder is able to handle script information for locales. The documentation of the Builder class also includes this example code:

Locale aLocale = new Locale.Builder().setLanguage("sr")
                                     .setScript("Latn")
                                     .setRegion("RS")
                                     .build();

By using the builder you would have to do the splitting of the string yourself and also removal of any unsupported characters like #.

Using the 3-arg contructor java.util.Locale.Locale(String, String, String) is not correct since you probably don't intend to specify a variant using Latn but a script instead.

If the format is consistent (your input looks always the same) you can split by # and by _ and get the parts.

See the following example:

var input = "az_AZ#Latn"
var lns = input.split("#")
var l = lns[0].split("_")
var locale = new Locale.Builder()
                 .setLanguage(l[0])
                 .setRegion(l[1])
                 .setScript(lns[1])      
                 .build()
             
locale.getLanguage() // ==> "az"  
locale.getCountry() // ==> "AZ"  
locale.getScript() //==> "Latn"
Related