I'm using NumberFormat's format() method to format currency in my application. When obtaining the currency instance, I'm not passing any locale to the method.
I've deployed this code to my app cluster which contains two nodes/servers. Interestingly, on one of the app server, the formattedAmmt is $xxxx.xx but on the other one it is ¤xxxx.xx. As far as I understand, this character is a universal currency symbol and JDK uses this when no particular locale is available. Is my understanding correct? If yes, how come it is working on one of the app server but not on the other? We are not seeing any default locale or such properties in app server/JVM properties.
double amount = xxxx.xx;
String formattedAmt = NumberFormat.getCurrencyInstance().format(amount);
PS: I'm deploying this app to WebSphere app server cluster which is using JDK 1.6.
Based on the java doc : https://docs.oracle.com/javase/6/docs/api/java/text/NumberFormat.html#getCurrencyInstance()
public static final NumberFormat getCurrencyInstance()
Returns a currency format for the current default locale.
It will base on the current locale of the server. That's why you may have two differents behavior.
If you want to specify the local, you have to use the following method:
public static NumberFormat getCurrencyInstance(Locale inLocale)
Returns a currency format for the specified locale
Related
Recently we migrated java code to OCI environment from AWS environment.
Below is the code which is giving issue.
sql.addSQLToWhereClause(XXXTable, "? between table1.start_date and table1.end_date")
.addSQLToWhereClause(YYYTable, "table1.ORG_ID = ? ")
.addSQLToWhereClause(XXXTable, "table1.LANG_CODE = ? ")
.bind(new Date())
.bind(ConstValues.ORG_ID)
.bind(locale.toString().toUpperCase());
In AWS environment it is working fine, but in OCI environment we are getting error:
ORA-01830: date format picture ends before converting entire input string
We are getting this error because .bind(new Date()) is putting '07-JAN-2021 10:49:04' in the first parameter. But expected value is '07-JAN-2021'
Please suggest why this additional information is coming in current date and how can we remove it without changing java code.
Thanks
Rahul
Object instances of Java's java.util.Date class always had the time portion in it. Why it should behave differently on AWS … – no idea!
But I assume that the implementation of bind(java.util.Date) is different in those environments, because the implementation of Date.toString() will come with a completely different output than that shown in the question.
So please check the version for the library that provides the respective class.
I have 2 string files to 2 languages in my android app, PT and EN. But I need to know which is the string file in use because I need to add in my SQLite database the current language in use.
Actually, I'm using this code to detect the current language in my SQLite database, but this function only works if the user changes the language manually in config screen. because I don't know how to get the first language selected when the user opens the application in the first time.
if(!dbl.selectIni().getCurrent_lang().equalsIgnoreCase("system")){
String languageToLoad = dbl.selectIni().getCurrent_lang();
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
}
You can use:
Locale.getDefault().getLanguage();
Or use the following code if you want to get the Locale when user change language from setting:
defaultLocale = Resources.getSystem().getConfiguration().locale;
It gets the system locale, no matter which default locale is set for the app/activity.
Read https://developer.android.com/reference/android/content/res/Resources.html#getSystem%28%29
But please remember that Resources.getSystem() references to the system resources and might cause a crash if used incorrectly.
For other option you can use the following:
Locale current = getResources().getConfiguration().locale;
From https://stackoverflow.com/a/14389640/4758255
And please be noted that this has been deprecated in the Configuration class, see the latest docs for this advice: locale This field was deprecated in API level 24. Do not set or read this directly. Use getLocales() and setLocales(LocaleList). If only the primary locale is needed, getLocales().get(0) is now the preferred accessor.
When my app loads, I get device's settings in order to display dates/times according to user's locale. As seen on the image below, the pattern is correct, but the am/pm marker is not translated to the corresponding language (in this case language is Greek, local is "el_GR"). Is there a way to fix that?
"am/pm" should be automatically translated to "πμ/μμ"
public static final DateFormat USER_DF_TIME = DateFormat.getDateTimeInstance(DateFormat.SHORT,
DateFormat.SHORT, Locale.getDefault());
After further investigation, I found a similar bug for Java 6, "Swedish localization has incorrect am/pm markers".The bug was reported back in 2007 and was finally resolved in 2011.
Also, according to the official Oracle page "The set of supported locales varies between different implementations of the Java Platform Standard Edition (Java SE)".
Testing my code on various devices I found out that it worked correctly on android 4.1.2 and 4.4, but the problem remains for my android 4.1.1 device. Given that old android's Java version is similar to Java 6 I infer that it's a Java language problem that is solved in newer versions.
I don't see an problem with your code.
private static final Locale GREEK_LOCALE = new Locale("el", "GR");
public static final DateFormat USER_DF_TIME = DateFormat.getDateTimeInstance(DateFormat.SHORT,
DateFormat.SHORT,GREEK_LOCALE );
String dateString =USER_DF_TIME.format(new java.util.Date());
System.out.println(dateString);
Returning 15/5/2014 2:11 μμ properly ( I am in EST now)
Seems you have issues with default locale.
Follow
https://stackoverflow.com/a/4212671/2182351 to get correct locale
I am running my Java app on a Windows 7 machine where my regional settings are set up to format dates as YYYY-mm-dd and time as HH:mm:ss (e.g. "2011-06-20 07:50:28"). But when I use DateFormat.getDateTimeInstance().format to format my date I do not see that instead I get "20-Jun-2011 7:50:28 AM". What do I need to do to format dates in the way that my customers have their OS setup to display dates?
Here is what my code in question looks like:
File selGameLastTurnFile = selectedGame.getLastTurn ().getTurnFile ();
Date selGameModifiedDate = new Date (selGameLastTurnFile.lastModified());
if (selectedGame.isYourTurn ()) {
gameInfo = Messages.getFormattedString ("WhoseTurnIsIt.Prompt.PlayTurn", //$NON-NLS-1$
FileHelper.getFileName (selGameLastTurnFile),
DateFormat.getDateTimeInstance().format(selGameModifiedDate));
} else {
gameInfo = Messages.getFormattedString ("WhoseTurnIsIt.Prompt.SentTurn", //$NON-NLS-1$
selGameLastTurnFile.getName (),
DateFormat.getDateTimeInstance().format(selGameModifiedDate));
}
The Messages.getFormattedString calls are using MessageFormat to put the date into a sentence that will look like this:
Play the turn 'QB Nat vs Ian 008' (received 20-Jun-2011 7:50:28 AM)
However my OS settings are setup to format the date as I described above and I expected to see this:
Play the turn 'QB Nat vs Ian 008' (received 2011-06-20 07:50:28)
I searched here and other Java programming sites and could not find the answer but this seems like such an obvious thing to want to do that I feel like I am missing something obvious.
First you have to tell Java what your system LOCALE looks like.
Check Java System.
String locale = System.getProperty("user.language")
And then format the date accordinly (SimpleDateFormat)
SimpleDateFormat(String pattern, Locale locale)
Refer to the practical Java code for a working example...
String systemLocale = System.getProperty("user.language");
String s;
Locale locale;
locale = new Locale(systemLocale );
s = DateFormat.getDateInstance(DateFormat.MEDIUM, locale).format(new Date());
System.out.println(s);
// system locale is PT outputs 16/Jul/2011
locale = new Locale("us");
s = DateFormat.getDateInstance(DateFormat.MEDIUM, locale).format(new Date());
System.out.println(s);
// outputs Jul 16, 2011
locale = new Locale("fr");
s = DateFormat.getDateInstance(DateFormat.MEDIUM, locale).format(new Date());
System.out.println(s);
// outputs 16 juil. 2011
Oracle JDK 8 fully supports formatting using user-customized OS regional settings.
Just set system property java.locale.providers=HOST
According to https://docs.oracle.com/javase/8/docs/technotes/guides/intl/enhancements.8.html:
HOST represents the current user's customization of the underlying
operating system's settings. It works only with the user's default
locale, and the customizable settings may vary depending on the OS, but primarily Date, Time, Number, and Currency formats are supported.
The actual implementation of this formatter is available in the class sun.util.locale.provider.HostLocaleProviderAdapterImpl.
If using system property is not acceptable (say, your don't want to affect the whole application), it's possible to use that provider class directly. The class is internal API, but can be reached using reflection:
private static DateFormat getSystemDateFormat() throws ReflectiveOperationException {
Class<?> clazz = Class.forName("sun.util.locale.provider.HostLocaleProviderAdapterImpl");
Method method = clazz.getMethod("getDateFormatProvider");
DateFormatProvider dateFormatProvider = (DateFormatProvider)method.invoke(null);
DateFormat dateFormat = dateFormatProvider.getDateInstance(DateFormat.MEDIUM, Locale.getDefault(Locale.Category.FORMAT));
return dateFormat;
}
You can't do this in pure Java. There is no way Sun/Oracle could make this system independent.
A quick browse of the .NET libraries gives this page - to quote:
The user might choose to override some of the values associated with the current culture of Windows through the regional and language options portion of Control Panel. For example, the user might choose to display the date in a different format or to use a currency other than the default for the culture. If the CultureInfo.UseUserOverride property is set to true, the properties of the CultureInfo.DateTimeFormat object, the CultureInfo.NumberFormat object, and the CultureInfo.TextInfo object are also retrieved from the user settings.
I would suggest that you do this in a way that is system dependent upon Windows if you need this functionality (e.g. access the Windows registry as #laz suggested).
I found this Java utility class by JetBrains that retrieves all the custom locale settings from the OS (both from Windows and Mac) and does the correct formatting for you:
https://github.com/JetBrains/intellij-community/blob/master/platform/util/src/com/intellij/util/text/DateFormatUtil.java
It's under the Apache 2.0 license so you can probably use it in your project.
I looks like you will need to access the Windows registry for this. See this question for various solutions to that read/write to Windows Registry using Java.
Once you choose one of the many methods of accessing the registry you will need to get the correct key from the registry for the format. This document indicates the key to use is HKEY_USERS\.Default\Control Panel\International.
When using GNOME in Linux, you can use the gconftool command similar to the reg command for Windows as mentioned in the prior links about the Windows registry. I see the key /apps/panel/applets/clock_screen0/prefs/custom_format in my configuration, though it is blank since I am using the default:
gconftool -g /apps/panel/applets/clock_screen0/prefs/custom_format
I'm not sure if that is the value you'd want to use for your purposes or not.
On Mac OS, I'm not sure what you would do.
java -Djava.locale.providers=HOST,CLDR,COMPAT YourProgram
Date and time formats are part of Java’s locale data. Java can get its locale data from up to four sources. Which ones it uses is controlled by the java.locale.providers system property. Default up to Java 8 was JRE,SPI. From Java 9 it’s CLDR,COMPAT. None of these will get you the date and time data from the operating system, but you can get them by supplying the HOST locale provider, for example as in the command line above. When running your program with this property definition, you may for example have:
DateTimeFormatter systemFormatter
= DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL);
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Africa/Bangui"));
String formattedDateTime = now.format(systemFormatter);
System.out.println(formattedDateTime);
This will print the current date and time in the format defined by the underlying operating system. To the extend that the operating system supports it you can vary the length of the output by using format styles FULL, LONG, MEDIUM and SHORT.
For most purposes you will want to have a DateTimeFormatter knowing the format as in the above code. In the rare case where you want to know a format pattern string that is possible too:
String osFormat = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
FormatStyle.SHORT, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.getDefault());
The first argument to getLocalizedDateTimePattern is the date format style. The second is the time style.
Perhaps I'm misunderstanding what you're getting at here but you need to use the Locale.
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE);
By using Locale you can control what format for what region you're using.
What is the correct way of knowing operating system language (locale) from java code?
I have tried
Locale.getDefault()
System.getProperties("user.language")
etc.
but they are not correct nothing actually displays the "System Locale" which is available by the command "systeminfo" in windows.
Please help.
The Windows XP systeminfo command displays lots of stuff, but the relevant information is this:
System Locale: en-us;English (United States)
Input Locale: en-us;English (United States)
To get equivalent information in Java, use Locale.getDefault() to get the Locale that Java is using, and use methods on the Locale object such as getCountry(), getLanguage() to get details. The information is available using ISO codes and as human readable/displayable names.
Note that Locale.getDefault() gives you the locale that Java picks up from the environment when it starts, this may or may not be the same as the "system" locale. To definitively get the "system" locale in Java you would need to do platform specific things. IMO, it is simpler to make sure that Java gets started with the system locale ... if you really need that information.
UPDATE: Apparently, Java 7 has changed the way that the locale information used by getDefault() is determined on Windows; see https://stackoverflow.com/a/8319889/139985
What about
System.getProperty("user.country");
System.getProperty("user.language");
Returns in my case
user.country=DE
user.language=de
You easily can generate the locale from this information. Local is 'language'_'country' so in my case
de_DE
How about using the default locale?
Locale locale = Locale.getDefault();
String lang = locale.getDisplayLanguage();
String country = locale.getDisplayCountry();
This returns me my current language and country as per the Windows systeminfo command. Is this what you're looking for? (If you want the 2-character codes for language/country, you can just use getLanguage() or getCountry()).
To be precise, you can try following code:
public Locale getLocale() {
if (this.locale == null) {
this.locale = new Locale(System.getProperty("user.language"), System.getProperty("user.country"));
}
return this.locale;
}