Reputation: 43841
What's the locale code for Hebrew in Android resources, like strings (values-XX)? And where to find other codes?
Thanks in advance.
Upvotes: 23
Views: 23149
Reputation: 794
There's always been a problem with how Java treated the Hebrew locale. While the ISO_639-1 language codes standard defined 'he' for Hebrew, Java java.util.Locale class included both 'he' and 'iw' codes, and the java.util.ResourceBundle class was treating both 'he' and 'iw' as 'iw' and it was loading the 'iw_' resources instead of 'he_'. If you asked for either locale 'he' or locale 'iw', the resource that would end up being loaded, would be the 'iw_' resource, which must have existed. You could not get an 'he_' resource to be loaded.
Starting with Java 17, the behavior seems to had been changed in favor of the correct language code 'he'. If you have both 'he_' and 'iw_' resources, it makes no difference whether you ask for locale 'he' or 'iw'. It is always the 'he_' resource, which ends up being loaded. It is only if the 'he_' resource is non existent, and an 'iw_' resource exists, that it gets loaded. So it seems Java 17 'wants' us to revert back to the correct ISO language codes.
EDIT: This new behavior can be reverted back to pre Java 17 defaults with the java.locale.useOldISOCodes system property set to true.
Here's a small Java program to demonstrate this behavior with the corresponding resource bundles to be placed in package com.acme.locale with the main program:
com.acme.locale.Locales Main class:
public class Locales {
public static void main(String[] args) {
System.out.printf("Java version: %s%n", Runtime.version().feature());
String language = "iw";
Locale locale = new Locale(language);
ResourceBundle rb = ResourceBundle.getBundle("com.acme.locale.messages", locale);
System.out.printf("%nLanguage Code: %s%n", language);
System.out.printf("Resource Bundle Locale: %s_%s%n",rb.getLocale().getLanguage(),rb.getLocale().getCountry());
System.out.printf("message: %s%n", rb.getString("message"));
language = "he";
locale = new Locale(language);
rb = ResourceBundle.getBundle("com.acme.locale.messages", locale);
System.out.printf("%nLanguage Code: %s%n", language);
System.out.printf("Resource Bundle Locale: %s_%s%n",rb.getLocale().getLanguage(),rb.getLocale().getCountry());
System.out.printf("message: %s%n", rb.getString("message"));
}
}
messages.properties (default resource)
message=This is a en_US locale message.
messages_iw.properties
message=\u05D4\u05D5\u05D3\u05E2\u05EA \u05D1\u05D3\u05D9\u05E7\u05D4 \u05D1\u05E2\u05D1\u05E8\u05D9\u05EA locale iw_
messages_he.properties
message=\u05D4\u05D5\u05D3\u05E2\u05EA \u05D1\u05D3\u05D9\u05E7\u05D4 \u05D1\u05E2\u05D1\u05E8\u05D9\u05EA locale he_
Running this with Java 16 yields the following output:
Java version: 16
Language Code: iw
Resource Bundle Locale: iw_
message: הודעת בדיקה בעברית locale iw_
Language Code: he
Resource Bundle Locale: iw_
message: הודעת בדיקה בעברית locale iw_
If you remove or rename the 'messages_iw.properties' resource, you'll end up loading the default English resource 'messages.properties'.
Running this example with Java 17 on the other hand, yields the following output:
Java version: 17
Language Code: iw
Resource Bundle Locale: he_
message: הודעת בדיקה בעברית locale he_
Language Code: he
Resource Bundle Locale: he_
message: הודעת בדיקה בעברית locale he_
So, it seems it's always trying to load the 'messages_he.properties' resource. However, if you remove or rename the 'messages_he.properties' resource, lo and behold, the 'messages_iw.properties' resource gets loaded.
It looks like from Java 17 on, no more trickery and magic is required with the naming strategy of Hebrew resource bundles. Just use the 'he' ISO language code and you should be fine. It's better late than never, as this had always been a pain and caused lot's of problems.
Upvotes: 5
Reputation:
The language is defined by a two-letter ISO 639-1 language code, optionally followed by a two letter ISO 3166-1-alpha-2 region code (preceded by lowercase "r").
from Providing Resources
According to the linked table, he
is the qualifier for hebrew.
Note: Some devices use iw
instead, as Error 545 noted in the comments, so you better check for both cases. See this question for more information.
Upvotes: 23
Reputation: 159
I think that in practice, this is not the case. From the localization guide: "Note that Java uses several deprecated two-letter codes. The Hebrew ("he") language code is rewritten as "iw"..."
Upvotes: 7