In Java it is easy enough to get the default Locale, but is there a way to get the short code that you see so often in websites such as lang=en or lang=zh
I need to send to information to a website but need the short code so the response will be in the correct language.
Locale.getDefault().getLanguage();
Use the Locale.getLanguage() method (API Link)
Returns the language code for this locale, which will either be the empty string or a lowercase ISO 639 code.
ISO-639 is the standard for two-letter language codes. See here for the list.
Related
How can I use an unsupported Locale (eg. ar-US) in JAVA 11 when I output a number via String.format()?
In Java 8 this worked just fine (try jdoodle, select JDK 1.8.0_66):
Locale locale = Locale.forLanguageTag("ar-US");
System.out.println(String.format(locale, "Output: %d", 120));
// Output: 120
Since Java 11 the output is in Eastern Arabic numerals (try jdoodle, use default JDK 11.0.4):
Locale locale = Locale.forLanguageTag("ar-US");
System.out.println(String.format(locale, "Output: %d", 120));
// Output: ١٢٠
It seems, this problem comes from the switch in the Locale Data Providers form JRE to CLDR (source: Localization Changes in Java 9 by #mcarth). Here is a list of supported locales: JDK 11 Supported Locales
UPDATE
I updated the questions example to ar-US, as my example before didn't make sense. The idea is to have a format which makes sense in that given country. In the example it would be the United States (US).
The behavior conforms to the CLDR being treated as the preferred Locale. To confirm this, the same snippet in Java-8 could be executed with
-Djava.locale.providers=CLDR
If you step back to look at the JEP 252: Use CLDR Locale Data by Default, the details follow :
The default lookup order will be CLDR, COMPAT, SPI, where COMPAT
designates the JRE's locale data in JDK 9. If a particular provider
cannot offer the requested locale data, the search will proceed to the
next provider in order.
So, in short if you really don't want the default behaviour to be that of Java-11, you can change the order of lookup with the VM argument
-Djava.locale.providers=COMPAT,CLDR,SPI
What might help further is understanding more about picking the right language using CLDR!
I'm sure I'm missing some nuance, but the problem is with your tag, so fix that. Specifically:
ar-EN makes no sense. That's short for:
language = arabic
country = ?? nobody knows.
EN is not a country. en is certainly a language code (for english), but the second part in a language tag is for country, and EN is not a country. (for context, there is en-GB for british english and en-US for american english).
Thus, this is as good as ar (as in, language = arabic, not tied to any particular country). Even if you did tie it to some country, that is mostly immaterial here; that would affect things like 'what is the first day of the week' ,'which currency symbol is to be presumed' and 'should temperatures be stated in Kelvin or Fahrenheit' perhaps. It has no bearing on how to show digits, because that's all based on language.
And language is arabic, thus, ١٢٠ is what you get when you try ar as a language tag when printing the number 120. The problem is that you expect this to return "120" which is a bizarre wish1, combined with the fact that java, unfortunately, shipped with a bug for a long long time that made it act in this bizarre fashion, thinking that rendering the number 120 in arabic is best done with "120", which is wrong.
So, with that context, in order of preference:
Best solution
Find out why your system ends up with ar-EN and nevertheless expects '120', and fix this. Also fix ar-EN in general; EN is not a country.
More generally, 'unsupported locale' isn't really a thing. the ar part is supported, and it's the only relevant part of the tag for rendering digits.
Alternatives
The most likely best answer if the above is not possible is to explicitly work around it. Detect the tag yourself, and write code that will just respond with the result of formatting this number using Locale.ENGLISH instead, guaranteeing that you get Output: 120. The rest seems considerably worse: You could try to write a localization provider which is a ton of work, or you can try to tell java to use the JRE version of the provider, but that one is obsoleted and will not be updated, so you're kicking the can down the road and setting yourself up for a maintenance burden later.
1.) Given that the JRE variant actually printed 120, and you're also indicating you want this, I get that nagging feeling I'm missing some political or historical info and the expectation that ar-EN results in rendering the number 120 as "120" is not so crazy. I'd love to hear that story if you care to provide it!
Do we have any java libraries to convert 3 letter language code to its corresponding language with localization support?
Like,
ENG -> English
PS: I guess its a bad question. But, google was of not a good help. Hence, turning to you all. Probably, my search term was not accurate.
Use Locale's getDisplayLanguage() method:
Locale eng = Locale.forLanguageTag("ENG"); // Make a locale from language code
System.out.println(eng.getDisplayLanguage()); // Obtain language display name
Demo.
I do not know about a Java library but this might help.
https://www.loc.gov/standards/iso639-2/php/code_list.php
It has the data you are looking for. You might have to scrape it off the page and put it into your Java code.
I'm using a TTS method on Android which takes a Locale instance as an argument. So I googled the class Locale and found some example code. But I don't understand what is different among usages below because I tested them all with a TTS method and it seems to work all the same to me.
Locale("ja")
Locale("ja_JP")
Locale("ja", "JP", "")
Locale.JAPAN
Locale.JAPANESE
Are there any differences?
The documentation for the Locale class describes this in (almost excruciating) detail. The valid language, country, and variant codes are described in ISO 639.
Here are the differences between the five examples you give:
ja simply describes the Japanese language with no country.
ja_JP specifies both the Japanese language and the country of Japan
The three parameter constructor splits off the language, country, and variant into separate arguments. Locale("ja", "JP", "") is equivalent to Locale("ja_JP") since no variant is provided.
Locale.JAPAN is a constant shortcut for ja_JP (the country of Japan).
Locale.JAPANESE is a constant shortcut for ja (the Japanese language).
What does this all mean? Well, it depends on where it is used. Locales are used with a number of different APIs, including the date-time APIs, text-to-speech APIs, and more.
In the context of text-to-speech, the locale can be used in a number of ways, such as:
Selecting the appropriate voice to use
Applying the proper inflection for certain words. Different locales may speak the same word in the same language differently.
Translating certain non-words into speech. For instance, different locales may speak numbers or fractions differently.
In general, you want to be as specific and accurate as possible when selecting a Locale.
I was wondering if anyone knows how to get formatted or styled codes from the Locale class. What i would like to see is "en_US" for English for US. For example, if i detect a language from Firefox it comes back as "en-us,en;q=0.5". Later when I want to output it (using getLanguage() or toString()) it comes back as "en-us,en;q=0.5" instead of "en_US". I tried various functions, but they all seem to return the string that was used to generate the Locale in the first place.
These values go into various UI elements and config files, so it would be nicer to have them looking the same regardless of who or how it was generated and also comparison is not easy when they are converted to strings (have to be).
Cheers and Thanks!
NOTE: I am asking this because we have legacy code that does alot (and i really mean most) of things when data is in string/xml format, so formatting is crucial.
Locale#toString() returns what you want.
Here's the thing: the languages you detect from Firefox use the format specified in RFC 2616, which is the HTTP specification. This is a different format from anything you'll see in a Java Locale because that format is very much HTTP-specific.
The problem is the meaning on what you are trying to print.
en-us,en;q=0.5
Means that the preference quality of the english language is 50% and it can be identified as en-us or en.
In the case you get in an http request
Accept-Language: da, en-gb;q=0.8, en;q=0.7
it means: "I prefer Danish, but will accept British English and other types of English"
so first you will have to decode your http request according to the specification and then get the Locales
I've been tasked with the awesome job of generating a look-up table for our application culture information. The columns I need to generate data for are:
Dot Net Code
Version
Culture Name
Country Name
Language Name
Java Country Code
Java Language Code
Iso Country Code
Iso Language Code
I have found the globalization name space, but I'm sure someone out there has asked the same question, or there is a table already available.
Thanks for any help
Java uses the 2-letter ISO country and language codes. I recommend getting rid of the "Java Country Code" and "Java Language Code" fields in your lookup table, since they would be redundant.
I assume that wherever you get your ISO country and language codes, you'll find their corresponding names in English. However, the Java Locale API will give also you the localized names for the country and language, if you need them. (I.e., what is America called in Japan?)
For example, you can do this:
Locale l = Locale.ITALY;
System.out.println(l.getDisplayCountry() + ": " + l.getDisplayLanguage());
System.out.println(l.getDisplayCountry(l) + ": " + l.getDisplayLanguage(l));
Which, running in the US English locale prints:
Italy: Italian
Italia: italiano
Note that you can obtain 3-letter ISO codes from the Locale class, but when constructing them, be sure to only use 2-letter codes.
That's strange, the last time I visited this page, someone had beaten me to posting the links to the Java references for Localization.
However, since their post is gone, here's what I was writing before they beat me to it.
Java uses two ISO standards for localization with java,util.Locale.
2-letter ISO-639 for language.
2-letter ISO-3166 for country.
Java uses Locales to store this information. Most of all the information you need regarding it can be found on Sun's Internationalization page. Java uses a syntax similar to the "en-us" syntax, however rather than using a hyphen it delineates with an underscore.
I'm guessing that you mean Localization or Internationalization or i18n.
Try this tutorial:
http://java.sun.com/docs/books/tutorial/i18n/index.html
Good Luck,
Randy Stegbauer