Hi I am struggling to format numbers like the documentation for NumberFormat.getInstance() says.
(Windows 7, NetBeans, Java 7)
I have first gone into regional settings and removed us english, us english keyboards and everything. I set it all to French and France. I even rebooted my pc. My code is:
System.setProperty("user.language", "fr");
System.setProperty("user.country", "FR");
System.setProperty("user.language.display", "fr");
System.setProperty("user.country.display", "FR");
System.setProperty("user.language.format", "fr");
System.setProperty("user.country.format", "FR");
Locale locale = new Locale("French", "France");
Locale.setDefault(locale);
Locale.setDefault(Locale.Category.DISPLAY, locale);
Locale.setDefault(Locale.Category.FORMAT, locale);
java.text.NumberFormat nf = java.text.NumberFormat.getInstance();
System.out.println(nf.format(4.5));
Despite all of this, the program prints "4.5". I don't understand, for French France this should be "4,5". What more do I need to do?
This is the problem:
Locale locale = new Locale("French", "France");
It should be:
Locale locale = new Locale("fr", "FR");
Or just use Locale.FRENCH.
Additionally, you don't need to set any properties or change the default locale. Just fetch the NumberFormat for the locale you're interested in.
It's a lot easier than that...
Locale locale = Locale.FRENCH;
will initialize the variable with the french locale, and
java.text.NumberFormat nf = java.text.NumberFormat.getInstance(locale);
will get you a NumberFormat for that locale.
EDIT: as you're using NetBeans, two tips to avoid this kind of trouble in the future:
When you type
Locale locale = new Locale(
followed by ctrl-space NetBeans will pop up a list of possible completions of that statement, with for each alternative a small window showing the JavaDoc.
Alternatively, when the cursor is on Locale NetBeans will bring up a browser window with the JavaDoc when you press Alt-F1 or rightclick, Show JavaDoc.
Java's library is well documented, and having the documentation come up with just one keystroke is a real timesaver.
This is a very old question, but I would like to report I've just found what seems to be a bug in the JVM implementation for OSX (Mac only bug).
This is a small piece of code that shows the problem:
public static void main(String[] args) {
DecimalFormatSymbols d = DecimalFormatSymbols.getInstance(Locale.getDefault(Locale.Category.FORMAT));
System.out.println(System.getProperty("user.language.format"));
System.out.println(System.getProperty("user.language"));
System.out.println(d.getDecimalSeparator());
System.out.println(d.getGroupingSeparator());
Locale l = Locale.getDefault();
System.out.println("Language: "+l.getLanguage());
System.out.println("Country: "+l.getCountry());
System.out.println("Variant: "+l.getVariant());
System.out.println("Tag: "+l.toLanguageTag());
Currency c = Currency.getInstance(l);
System.out.println("Code: "+c.getCurrencyCode());
NumberFormat nc = DecimalFormat.getCurrencyInstance();
NumberFormat ni = DecimalFormat.getNumberInstance();
}
In my case, the output is:
en
es
.
,
Language: es
Country: ES
Variant:
Tag: es-ES
Code: EUR
Im my operating system I've set es_ES but due to a bug. The JVM system property user.language.format is not properly initialised and this is the source of several pains.
Related
Like when i take input (he-IL) then output comes like "iw_IL". But i do not want this convert to old iso.
public static void main(String[] args) {
Locale locale = getLocaleIn("he-IL");
System.out.println(locale.toString());
}
private static Locale getLocaleIn(String langCode) {
LocaleCode code = LocaleCode.getByCodeIgnoreCase(langCode);
Locale locale = code.toLocale();
return locale;
}
OutPut:
iw_IL,
Expected Output:
he-IL
Main Problem in Here, In Java Locale.Class:
Finally I Want an Locale Object without Converting to old ISO.
You should avoid non-standard 3rd party classes in problem descriptions, especially when they do not contribute to the problem at all.
We can simply use
Locale locale = new Locale("he", "IL");
System.out.println(locale.toString());
locale = new Locale("iw", "IL");
System.out.println(locale.toString());
and get
iw_IL
iw_IL
under JDK 8, which is in line with the documentation:
This constructor accepts both the old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other API on Locale will return only the OLD codes.
This has changed with JDK 17:
Obsolete ISO 639 codes ("iw", "ji", and "in") are mapped to their current forms.
and running the same example program with JDK 17 accordingly now prints
he_IL
he_IL
So the cleanest and probably the only solution to your issue would be updating the Java version. Any patch forcing Locale to return the new code in older versions may cause compatibility problems with other components of the runtime relying on the old behavior.
So a few days ago I encountered a weird problem however, I didn't change any that kind of code. The problem is the format I'm getting from my method which I used for years. All commas are now spaces (blank fields) and I have no idea what is causing this.
public static String toFancyCost(int num) {
return NumberFormat.getInstance().format((Integer) num);
}
Before even this happened the String I received was looking like for example 2,181,273 and not like 2 181 273.
You must have changed your system locale by accident. The implementation of NumberFormat.getInstance() (on 1.8.0_131):
public final static NumberFormat getInstance() {
return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
}
It uses formatting specified by the default locale. and the java docs on Locale.getDefault say:
The Java Virtual Machine sets the default locale during startup based
on the host environment. It is used by many locale-sensitive methods
if no locale is explicitly specified. It can be changed using the
setDefault method.
If you were to use NumberFormat.getInstance(Locale) you can specify which locale the NumberFormat should use.
Your systems default local is using a space as thousands separator, number format retured by getInstance() uses settings from system's default local.
As commented above, somehow the system default may have been modified. Let's stick the code to set the locale when formatting by using below to avoid any issues.
int number = 345678987;
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);// Locale.US or any other locale you required
String numberAsString = numberFormat.format(number);
System.out.println(numberAsString);
response:
345,678,987
when I use the below for example with Locale.CANADA_FRENCH
int number = 345678987;
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.CANADA_FRENCH);
String numberAsString = numberFormat.format(number);
System.out.println(numberAsString);
response:
345 678 987
So in your case also locale may have been causing issues, so please explictly set locale.
The problem that I'm running in to is when setting the Locale programmatically to Albanian (sq-AL) and Montenegran (sr-ME) the locale doesn't seem to be recognised as it defaults back to english. When setting Italian (it) or Spanish (es) there is no issues so I'm unsure what the problem could be. All string.xml's are in the correct format and named correctly. This is the code I am using to set the locale:
Context context = getBaseContext();
Resources res = context.getResources();
DisplayMetrics metrics = res.getDisplayMetrics();
android.content.res.Configuration conf = res.getConfiguration();
langCode = "sr-ME"; // Hard setting langCode for testing
Locale newLocale = new Locale( langCode ) ;
conf.setLocale( newLocale );
res.updateConfiguration( conf, metrics );
Much appreciated if anyone can help!
"sr-rME" seems to not exist so android reset to default. Here is an exhaustive list of supported languages of android, you may find your answer :
What is the list of supported languages/locales on Android?
In my opinion you should try something like that, because "sr-rME" is for value folder name :
`langCode = "sq"; // or 'sr-ME' for Montenegran
Locale newLocale = new Locale( langCode ) ;`
Else if Montenegran is your default phone language you can get it by typing that:
Locale current = getResources().getConfiguration().locale;
The problem was the way I was setting the locale. The correct way to set a locale when using region-specific locales is by using both arguments in initialising Locale. For sr-ME (Montenegran) it should be initialised like this:
Locale newLocale = new Locale( "sr", "ME" );
In Java I create Locale with Language and Country parameters
and then use appropriate date formats.
However Java does not support all Language_Country combinations and fallbacks to default locale formats (in my case en_US).
Is there a way to determine that fallback occured?
E.g:
When I create locale with Locale locale = new Locale("xx","xx");
then
((SimpleDateFormat)DateFormat.getDateInstance(DateFormat.SHORT,locale)).toLocalizedPattern();
returns M/d/yy so it fallbacks to en_US.
So i need something like
locale.isDefault
You can check that the locale is one of the available locales:
Set<Locale> locales = new HashSet<>();
Collections.addAll(locales, Locale.getAvailableLocales());
Locale locale = new Locale("xx", "xx");
System.out.println(locales.contains(locale)); //prints false
locale = new Locale("fr", "FR");
System.out.println(locales.contains(locale)); //prints true
Locale.getDefault().equals(locale)
I'm trying to format a date for a given locale new Locale("mk", "MK"). The locale is valid, it returns the country name and language properly. I want to use custom string, in my case "E, kk:mm" or "EEEE, kk:mm". I want the output to be "сабота, 12:00", but what I get is "7, 12:00".
This is how I use it and I tried many ways, but they all seem to behave the same.
SimpleDateFormat sdf = new SimpleDateFormat("EEEE, kk:mm", new Locale("mk", "MK));
sdf.format(new Date());
// output: 7, 12:30
Another method I tried
Calendar calendar = Calendar.getInstance(new Locale("mk", "MK"));
calendar.setTimeInMillis(new Date().getTime());
DateFormat.format("EEEE, kk:mm", calendar);
// output: Saturday, 12:30
I also tried using java.text.DateFormat instead android class, but no change.
The phone locale is set to English, but this is localized app, I want to show dates in a fixed locale format.
I've looked into many SO question regarding this issue and I wasn't able to find answer. I'm not interested in predefined formats, I want to use my own format and I want the date/month names to be formatted for the input locale.
I think the problem is that Macedonia is not a supported locale on the Android JVM. If you run your code as plain Java console app, it's fine. The method Locale.getAvailableLocales() returns 152 members in plain Java, only 88 in an Android emulator. If you have the code snippet:
Locale[] locales = Locale.getAvailableLocales();
String cCode;
for (Locale loc :locales){
cCode = loc.getCountry();
if (cCode.equalsIgnoreCase("MK"))
Toast.makeText(this, cCode, Toast.LENGTH_SHORT).show();
// Or System.out.println() in a Java app
}
Then the toast doesn't show for "MK" although it will println in the Java app
From documentation of SimpleDateFormat:
**Text**: For formatting, if the number of pattern letters is 4 or more,
the full form is used; otherwise a short or abbreviated form is used if
available. For parsing, both forms are accepted, independent of the
number of pattern letters.
So this should fix it:
SimpleDateFormat sdf = new SimpleDateFormat("EEEE, kk:mm", new Locale("mk", "MK"));
NickT was faster :-), so just adding to his answer: if you want to see your locales supported on Android, run:
for (Locale l:Locale.getAvailableLocales()) {
Log.d(l.getDisplayCountry(),l.toString());
}
and you will see that Macedonia is not on the list.