Skip to main content

Changes in Java 7 Locale

Posted by joconner on September 13, 2011 at 2:44 AM PDT

I admit that I haven't been particularly active in the i18n or Java standards bodies in the last few years. Pardon me, but I had a wild rumpus in a startup for almost 3 years, then joined Yahoo for a couple years, and BAM! ... during that time, the Unicode Consortium added emoji, and the Oracle Java folks overhauled the once relatively simple java.util.Locale class among other things. That'll teach me to turn my back on those folks.

You can almost forgive the Unicode people for their addition of emoji... BUT more interesting to me right now...have you seen java.util.Locale lately? What the heck happened there? Java 7 introduces Locale.Builder, Locale.Category, and a Locale.forLanguageTag method. With Java 7's support of BCP 47 (the best practices for language coding), the Locale got a beefy new Builder inner class to help with...well, to help with building BCP 47 compliant locales. More on this in a different post. With the BCP 47 support, I suppose you might need the forLanguageTag method too. Now here's what stumps me though -- that Category class!

As far as I can tell, this category is to help you differentiate a locale instance for two different purposes: user interface language and locale-sensitive data formats. The new categories are the following:

  • DISPLAY
  • FORMAT

Do we really need a separate Category class to make that explicit?

Locale has another new method: setDefault(Locale.Category, Locale newLocale). I can't wait to play with this a bit more. I suspect that this will set the default resource bundles (DISPLAY) for UI language and the default FORMAT for things like DateFormat, etc. However, I can't understand why these two categories are actually needed in the platform libraries. Convenience maybe? You could always use two different Locale instances for this in the past, but I suppose this makes that easier? I'll have to play around with these to find out more.

You can see this blog and followups on my own joconner.com site.

Related Topics >>

Comments

 Amazingly, this change broke our app. Quite aside ...

Amazingly, this change broke our app.

Quite aside from introducing the categories (which in my opinion is fine), they also changed the return value from Locale.getDefault() to return "en_US" instead of "en_AU" - Locale.getDefault(Locale.Category.FORMAT) is now the "en_AU". So all the formats throughout our app which was developed in JDK6 are now in the wrong locale and need to be manually fixed. It would have been nice if they at least kept the behaviour for the other method the same as before. It seems like they should have deprecated it, too, and they didn't.

Besides breaking our own code, it also breaks Joda Time, since they call Locale.getDefault() as well. So of course any application relying on Joda Time picking the right default locale for formatting dates is also broken. Now every time you use a DateTimeFormater, you have to manually set the locale appropriately. I'm sure they will get around to fixing this (hopefully sooner rather than later.)