I was struggling with date formatting in Kotlin.
Does someone know why using :
val locale = ConfigurationCompat.getLocales(Resources.getSystem().configuration).get(0)
java.text.DateFormat.getDateInstance(java.text.DateFormat.SHORT, locale).format(Date())
give me :
In FR_fr = 08/09/2022 (expected)
In EN_gb = 08/09/2022 (unexpected)
BUT
val currentLanguage = ConfigurationCompat.getLocales(Resources.getSystem().configuration).get(0).language
val locale = Locale(currentLanguage)
java.text.DateFormat.getDateInstance(java.text.DateFormat.SHORT, locale).format(Date())
gives me :
In FR_fr = 08/09/2022 (expected)
In EN_gb = 9/8/2022 (expected)
Is there a simpler way?
In the second one, while you are doing this,
ConfigurationCompat.getLocales(Resources.getSystem().configuration).get(0).language
it will give language as en.It will not give country variant english.It will return generic english locale.
So you should create locale like below.
val currentLanguage = ConfigurationCompat.getLocales(Resources.getSystem().configuration).get(0)
if (currentLanguage!=null) {
val currentLocale = Locale(currentLanguage.language, currentLanguage.country, currentLanguage.variant)
}
THis will create locale with en-GB in your case.
In the first one you are already getting locale object with en-GB.
en-GB and en has different formats of date.
08/09/2022 : en-GB
9/8/2022 : en
en-IN (Indian English) also will give 08/09/2022 as result.
The reason for the different results is because
in you first example, you work with actual en_GB/fr_FR locale,
but in the second example, your locale is only en/ fr.
That's because language/getLanguage() in this instance returns only en/ fr, without country specification.
So, I'd say, the first result (08/09/2022) is the correct one for en_GB. If you want a different date format you probably have to create your own one.
Related
How to programatically find the language the app is using. For example the device Locale is set to es_MX but my app supports only en_US and hence the app displays text only in English.
How to programatically find that app is using English and not Spanish in this case?
All the below code returns ex_MX
Locale locale = getResources().getConfiguration().getLocales().get(0);
Locale l = Resources.getSystem().getConfiguration().getLocales().get(0);
Locale l1 = Locale.getDefault();
Please Refer this given link's answer as you must get locale at the time of starting the app. If you will set your locale once in whole life cycle, you will get only the language as default as you set in the locale.
https://stackoverflow.com/a/23556454/6549856
You can get the system language.
Resources.getSystem().getConfiguration().locale.getLanguage();
for app default language
String CurrentLanguage = Locale.getDefault().getLanguage();
This is happening on all of the devices we have in Indonesia.
The country codes are correct, also the display language and ISO3 seem correct:
Locale.getDefault().getISO3Country() // "IDN"
Locale.getDefault().getDisplayCountry() // "Indonesia"
Locale.getDefault().getCountry() // "ID"
Locale.getDefault().getISO3Language() // "ind"
Locale.getDefault().getDisplayLanguage() // "Bahasa Indonesia"
But the normal language code is wrong, should be "id" instead of "in". And then android is also generating the wrong language_COUNTRY identifier, should be "id_ID" instead of "in_ID":
Locale.getDefault().getLanguage() // "in"
Locale.getDefault().toString() // "in_ID"
Is this a known problem? What can we do about it?
cyanide suggests just overwriting the locale, but what about the devices who really need to use "in" and not "id", it would be the wrong one for them then?
Well, found out why it is happening, see the Android Locale Constructor Reference:
ISO 639 is not a stable standard; some of the language codes it defines (specifically "iw", "ji", and "in") have changed. 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.
So not much we can do, use "in" inside the app for strings, etc. and convert it to "id" (or treat in as id) when talking to outside entities like backend servers.
Check language settings on your device. If all right, then your system is dodgy, so you may try to upgrade it. As a matter of fact, configuration can be changed prorammatiically
public void updateLocale(Resources rsrc) {
Configuration conf = rsrc.getConfiguration();
Locale locale = conf.locale;
if (locale.getCountry().equals("ID") && locale.getLanguage().equals("in")) {
conf.locale = new Locale("id", "ID");
rsrc.updateConfiguration(conf, rsrc.getDisplayMetrics());
}
}
However, it isn't really advisable;
I have a same experience and I found a reference in Android Developer Site
If you want to change old language code("he", "yi", and "id") to new one("iw", "ji", and "in"), you just use this API below
//kotlin
Locale.getDefault().toLanguageTag()
I am trying to get the date with this pattern - "dd/MM/yyyy".
So far i've used SimpleDateFormat to achieve it, but now i need to also support Chinese in my app and it's not giving me the result i need.
I'm trying to make it look like the pattern with attention to the locale:
English: 16/05/2016
Chinese: 2016年05月16日
I tried different options -
android.text.format.DateUtils.formatDateTime
android.text.format.DateFormat.getDateFormat
but couldn't get the result i wanted.
Thanks
If you want specific patterns, you have to test the locale and apply the format you want.
For your english and chinese formats :
CharSequence englishDate = DateFormat.format("dd/MM/yyyy", date);
CharSequence chineseDate = DateFormat.format("yyyy年MM月dd日", date);
Results are :
25/05/2016 and 2016年05月25日
I just ran into this problem when testing the locale set in the preferences against constant values:
(new Locale("en_US")).equals(Locale.US) == false
When looking at the details it turns out that new Locale("en_us") returns an object with a language code "en_us" and a country code that is a zero length string whereas Locale.US returns an object with language code "en" and country code "US". Locale("en","US") returns the same result as Locale.US so its easy to avoid this problem, but is this the expected behavior of the Locale constructors?
Locale constructors are working as expected. You can compare the locale objects like this:
(new Locale("en_US")).toString().equalsIgnoreCase((Locale.US).toString())
It will give you the expected value
What I want do do is to provide a ISO 3166-1 country code and retrive the name of that country in the current locale. For those of you who are familiar with iPhone, I have an an example of exactly what I want to do:
NSLocale* currentLocale = [NSLocale currentLocale];
NSString* countryName = [currentLocale displayNameForKey:NSLocaleCountryCode value:#"NO"];
In this case the variable countryName would contain "Norway" given the iPhone was running in an english locale.
What I have understood so far is that to get the current locale in the Android SDK by a simple static method of the Locale class.
Locale currentLocale = Locale.getDefault();
But Im stuck here...
Locale l = new Locale("en", "NO");
String norway = l.getDisplayCountry();
works for me. Just replace "NO" by the country you want and it should give you the name in your current default locale. The "en" is just there to fill in some language but it should not matter which you use (At least I hope that works for all combinations - have not tested them all)