Difference in initialization of a Locale object
Asked Answered
I

1

1

Is there any difference between this two ways of creating a Locale :

Locale uk    = Locale.UK;

Locale en_uk = new Locale("en", "UK");

The only difference I have noticed so far is that getDisplayCountry returns different values. The first United Kingdom and the second UK , which does not bother me very much. Is there besides that any difference? Especially because I would like to adopt the first style for other regions like Germany, France, Korea etc

Iridic answered 9/7, 2024 at 17:56 Comment(9)
That is because you need to use GB, not UK (the ISO 3166 two-letter country code for The United Kingdom of Great Britain and Ireland is GB).Centrosymmetric
Indeed new java.util.Locale("en", "UK").getISO3Country() throws an exception.Formidable
@MarkRotteveel You might want to re-post that as "and Northern Ireland" — an important difference, and a sensitive subject!Glasses
Also, to clarify @MarkRotteveel comment you need new Locale("en", "GB") (i.e. Locale.UK is perfectly fine, and there's no such thing as Locale.GB).Formidable
Thank you all. For my application it makes no big difference whether Uk or GB. But what I noticed when trying it out is that if you want to change the default language, the second option is correct. For example Locale ca = Locale.CANADA; , where it returns english as language. So If one needs french the second way is the correct oneIridic
Skip the constants; use Locale.of. Locale.of( "en" , "GB" ) for English in UK, Locale.of( "en" , "CA" ) for English in Canada, Locale.of( "fr" , "CA" ) for French in Canada.Glasses
There are online validators such as this one which will tell you that UK is not a valid region (country) subtag.Kristie
BTW the constant Locale.UK is basically the same as new Locale("en", "GB") (explaining the difference to new Locale("en", "UK") )Orsola
@BasilBourque Yes, I meant Northern Ireland... I should have copied it from Wikipedia instead of typing it out by hand. I guess my mind raced ahead of the words I was typing.Centrosymmetric
G
6

tl;dr

  • Wrong country code.
  • Do not use Locale constants. Use Locale.of.
Locale.of( "en" , "GB" )  // For English language, and cultural norms of United Kingdom.

Other examples:

  • Locale.of( "en" , "CA" ) for English in Canada.
  • Locale.of( "fr" , "CA" ) for French in Canada.
  • Locale.of( "en" , "US" ) for English in United States.

GB, not UK

For your purpose, the correct country code for the United Kingdom of Great Britain and Northern Ireland is GB, not UK, as commented by Mark Rotteveel.

CLDR

Modern Java (9+) uses by default the Common Locale Data Repository (CLDR) as the primary source of localization data. Entry # 827 in the CLDR shows a country code of GB for United Kingdom.

Standard country codes

The Javadoc for Locale states that the country/region code must be either:

If curious, dump to console:

Arrays.stream( Locale.getISOLanguages() ).forEach( System.out::println );  // All 2-letter country codes defined in ISO 3166.
Arrays.stream( Locale.getISOCountries() ).forEach( System.out::println );  // All 2-letter language codes defined in ISO 639.

The Javadoc also notes that a complete list can be found in the IANA Language Subtag Registry with a tip to search for Type: region. There we find this entry telling us to use GB for the United Kingdom.

%%
Type: region
Subtag: GB
Description: United Kingdom
Added: 2005-10-16
Comments: as of 2006-03-29 GB no longer includes the Channel Islands and
  Isle of Man; see GG, JE, IM
%%

Validator

The Comment by andrewJames points us to this online validator by Christoph Schneegans for IETF BCP 47 language tag with language and country code combined.

There we see en-UK fails, while en-GB passes.

Avoid Locale constants

You should ignore those constants defined on Locale class such as Locale.UK and Locale.CANADA_FRENCH. Their creation was a hasty poor decision in design. For more info, see my longer Answer.

Instead, in modern Java (19+), use the convenient static factory methods Locale.of.

Locale.UK, Locale.of( "en" , "GB" )

See Locale.of in action.

Locale locale = Locale.of( "en" , "GB" ) ; 
Glasses answered 9/7, 2024 at 18:15 Comment(2)
I’m curious, where did the Java team ask that programmers refrain from using the constants of Locale? I didn’t see it in that question or its answers.Anion
@Anion I have been trying to find a reference to that, having come across it earlier this week. But I have failed. So I'll delete that remark for now. Thank you for asking. I did find this old Sun article saying “you should probably just avoid these static objects altogether”. But that was just a remark in passing by a single individual, not the blanket policy statement I had in mind.Glasses

© 2022 - 2025 — McMap. All rights reserved.