How to get iso2code from a country name by locale - java

I have a form that user enter a country name, then I have to convert it to iso2 or iso3 code.
How is it possible? I prefer not to use map, as it seems not running on my Android app.
This code is for converthing iso2 to an actual name, I want the other way around:
Locale l = new Locale("", "CH");
System.out.println(l.getDisplayCountry());

Have you tried Locale.getISO3Country() ?
To actually do the conversion, you might need to loop through all the available locales and look for the one whose getDisplayCountry() matches your input country name.
It doesn't sound efficient (but you said to not use maps), but you might try something like:
Locale convertCountryNameToIsoCode(String countryName)
for(Locale l : Locale.getAvailableLocales()) {
if (l.getDisplayCountry().equals(countryName)) {
return l;
}
}
return null;
}
http://docs.oracle.com/javase/7/docs/api/java/util/Locale.html#getISO3Country()
However, if the input comes from a web form, than it would be easier to set the country code directly as the web form input value. If the input comes from an Android native App, then I'm not sure but I'd bet you might a similar thing

Related

Enum toString sometimes replacing i with ı

I recently got a report that a few Google Analytics event category names were being recorded with an i character with out a dot on top.
Pageviews and events occurring twice, once without dots over the i.
I had to look to believe it. Sure enough, I had an event called favorite and there was a handful called favorıte. Copy and paste that weird character into a terminal or a monospace font just to see how weird it is. favorıte
My first suspicion is my code where I generate the strings for the category names using toString on an enum.
public enum AnalyticsEvent {
SCREEN_VIEW,
FAVORITE,
UN_FAVORITE,
CLICK_EVENT,
... reduced for brevity;
public String val() {
return this.toString().toLowerCase();
}
}
Example of how that enum is used:
#Override
public void logSearchTag(String type, String value) {
...
logGAEvent(AnalyticsEvent.SEARCH_TAG.val(), type, value);
}
private void logGAEvent(String category, String action, String label) {
... // mGATracker = instance of com.google.android.gms.analytics.Tracker;
mGATracker.send(addCustomDimensions(new HitBuilders.EventBuilder()
.setCategory(category)
.setAction(action)
.setLabel(label))
.build());
...
}
I am going to solve this by actually assigning a string to the enums and instead return that in the val() function.
Though, I am curious if anyone knows why on a small handful of devices Enum.toString returns the enum name with that weird character replacing the i. I mean small. 8 out 50,000 is the average. Or is it possible that assumption is wrong and the error is on analytics service end somewhere? Really highly doubt that.
The String#toLowerCase method uses the default locale of the system. This use locale specific characters such as ı instead of i. In order to fix this problem call toLowerCase with a locale:
String test = "testString";
test.toLowerCase(java.util.Locale.ENGLISH) // Or your preferred locale

How to validate & instantiate Java Locale from strings?

My app is being fed string from an external process, where each string is either 2- or 5-characters in length, and represents a java.util.Locales. For example:
en-us
ko
The first example is a 5-char string where "en" is the ISO language code, and "us" is the ISO country code. This should correspond to the "en_US" Locale. The second example is only a 2-char string, where "ko" is the ISO language code, and should correspond to the "ko_KR" (Korean) Locale.
I need a way to take these strings (either the 2- or 5-char variety), validate it (as a supported Java 6 Locale), and then create a Locale instance with it.
I would have hoped that Locale came with such validation out of the box, but unfortunately this code runs without exceptions being thrown:
Locale loc = new Locale("waawaaweewah", "greatsuccess");
// Prints: "waawaaweewah"
System.out.println(loc.getDisplayLanguage());
So I ask, given me the 2 forms that these string will be given to me in, how can I:
Validate the string (both forms) and throw an exception for strings corresponding to non-existent or unsupported Java 6 Locales; and
Instantiate a new Locale from the string? This question really applies to the 2-char form, where I might only have "ko" and need it to map to the "ko_KR" Locale, etc.
Thanks in advance!
Locale.getISOCountries() and Locale.getISOLanguages()
return a list of all 2-letter country and language codes defined in ISO 3166 and ISO 639 respectively and can be used to create Locales.
You can use this to validate your inputs.
You have two options,
Use a library for doing this commons-lang has the LocaleUtils class that has a method that can parse a String to a Locale.
While your own method, the validation here is non trivial as there are a number of different sets of country codes that a valid for a Locale - see the javadoc
A starting point would be to split the String and switch on the number of elements:
public static Locale parseLocale(final String locale) {
final String[] localeArr = locale.split("_");
switch (localeArr.length) {
case 1:
return new Locale(localeArr[0]);
case 2:
return new Locale(localeArr[0], localeArr[1]);
case 3:
return new Locale(localeArr[0], localeArr[1], localeArr[2]);
default:
throw new IllegalArgumentException("Invalid locale format;");
}
}
Presumably you would need to get lists of all valid country codes and languages and compare the elements in the String[] to the valid values before calling the constructor.

Locale appending 'variation' to language and country code

LocaleContext.getLocale() returns the locale object currently as 'en_US_WOL'. I verified the locale object using breakpoint and looks like en- language English, US - country code of US, WOL - variation (a field of Locale object).
How and why is the variation field getting appending and returned for getLocale() method? and how can I stop that? (LocaleContext is of type ThreadLocal)
According to http://docs.oracle.com/javase/6/docs/api/java/util/Locale.html
The variant argument is a vendor or browser-specific code. For example, use WIN for Windows, MAC for Macintosh, and POSIX for POSIX. Where there are two variants, separate them with an underscore, and put the most important one first. For example, a Traditional Spanish collation might construct a locale with parameters for language, country and variant as: "es", "ES", "Traditional_WIN".
If you're after Locale for specific variant, I presume you can use this constructor:
Locale(String language, String country, String variant)
Or adjust your browser's locale settings (if your application involves browser at all)
I had a problem with this too. Unfortunately I haven't found any build-in method to nicely output lang-country code without Variant so I helped myself with such snippet (maybe would be handy to somebody) :
public static String getLanguageCode(Locale locale) {
StringBuilder sb = new StringBuilder();
sb.append(locale.getLanguage());
if (locale.getCountry() != null && locale.getCountry().length() > 0) {
sb.append("-");
sb.append(locale.getCountry());
}
return sb.toString();
}

Java - generating conditions from string

I'm trying to generate some conditions using string i get as input.
For example, i get as in put the string "length = 15" and i want to create from that the condition:
length == 15.
To be more specific, i have an int in my program called length and it is set to a specific value.
i want to get from the user a conditon as input ("length < 15" or "length = 15"....) and create an if statement that generates the condition and test it.
What is the best way of doing that?
Thanks a lot
Ben
Unless you're talking about code-generation (i.e. generating Java-code by input strings) you can't generate an if-statement based on a string.
You'll have to write a parser for your condition-language, and interpret the resulting parse trees.
In the end it would look something like this:
Condition cond = ConditionParser.parse("length = 15");
if (cond.eval()) {
// condition is true
}
Use a string tokenizer. The default method to distinguish between tokens (or the smallest parts of the input string) is white space, which is to your benefit.
check out javadocs for details:
http://docs.oracle.com/javase/1.3/docs/api/java/util/StringTokenizer.html
Depending on what restrictions you can place on your input format, you could consider using Rhino to embed Javascript. Your 'conditions' then just have to be valid JavaScript code. Something like this (disclaimer: haven't compiled it):
import javax.script.*;
public bool evalCondition (Object context, String javascript) {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
Object result = engine.eval(javascript);
Boolean condTrue = (Boolean)result;
return condTrue;
}
See the Embedding Rhino Tutorial for more details.

Temporary displaying text (not dates) in a different language

I'm trying to display some message on the screen in a different language (but keeping the dates in the default language, uk_eng), depending on what user is looking at the screen. Being only a temporary setting I was wondering what's the best way to do it in Java.
You could have message bundles for each Locale. Load these and display them appropriately when you identify the user's Locale.
An example is at http://java.sun.com/developer/onlineTraining/Programming/BasicJava2/int.html
You could load these in a web app too like http://www.devsphere.com/mapping/docs/guide/internat.html
If I see the problem well, you want to display messages with MessageFormat like this:
Object[] arguments = {
new Integer(7),
new Date(System.currentTimeMillis()),
"a disturbance in the Force"
};
String result = MessageFormat.format(
"At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
arguments);
(Example from javadoc)
I checked the source of the MessageFormat and I see that getLocale() is common for the whole message. You cannot make a distinct one for a parameter.
Why don't you make a parameter with the formatted date string itself? Like this:
Object[] arguments = {
new SimpleDateFormat("yyyyy.MMMMM.dd GGG hh:mm aaa", Locale.UK).format(new Date())
};
String result = MessageFormat.format(
"This is the date format which I always want independently of the locale: {1} ",
arguments);
The first parameter of the format methods may come from localized property files.

Categories

Resources