[TIMOB-27240] Android: Add Intl.NumberFormat support
GitHub Issue | n/a |
---|---|
Type | New Feature |
Priority | Medium |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2020-07-19T14:16:28.000+0000 |
Affected Version/s | n/a |
Fix Version/s | Release 9.1.0 |
Components | Android |
Labels | Intl, NumberFormat, android, format, locale, localization, parity |
Reporter | Hans Knöchel |
Assignee | Joshua Quick |
Created | 2019-07-12T18:31:32.000+0000 |
Updated | 2020-07-30T13:04:57.000+0000 |
Description
We use the
Intl.NumberFormat
class to format currencies, e.g.:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat
const value = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2
}).format(10.12);
console.log(value); // output: $10.12
It works fine on iOS but throws an error "Intl is not defined
", although the web docs indicate it [should work on V8](https://v8.dev/blog/intl).
Workaround until then is writing another native module:
@Kroll.module(name="TiCurrency", id="ti.currency")
public class TiCurrencyModule extends KrollModule
{
private static final String LCAT = "TiCurrencyModule";
private static final boolean DBG = TiConfig.LOGD;
@Kroll.method
public String format(KrollDict params)
{
double value = params.getDouble("value");
String currency = params.getString("currency");
NumberFormat format = NumberFormat.getCurrencyInstance(Locale.getDefault());
format.setCurrency(Currency.getInstance(currency));
return format.format(value);
}
}
Hmm... it looks like this is an optional feature that we have to #define-in via "V8_INTL_SUPPORT". https://github.com/v8/v8/search?q=V8_INTL_SUPPORT&unscoped_q=V8_INTL_SUPPORT Although I doubt it's that simple since the Android NDK itself does not support international locales. It only supports the default US-EN locale (ie: C++ std::locale::classic). That's why Titanium has to override the JS formatting functions and handle them on the Java side.
Same goes for
toLocaleDateString
btw. Having those cross platform would really be a benefit.Yes, I agree. Thanks for bringing this up.
I've looked into this. If we were to
#if-in
JSIntl
support into V8, we would have to include the ICU (International Components for Unicode) C++ library which is about 20 MB per architecture. This library is way too big and not mobile friendly. Especially since Google Play has an APK size limit of 100 MB. I think the best solution is for us to implementNumberFormat
support on the Java side.PR (master): https://github.com/appcelerator/titanium_mobile/pull/11698
manually rebase/merged to master, 9_1_X, 9_3_X
There's a bug with
formatToParts()
on Android 4.4. Fixed via PRs... PR (master): https://github.com/appcelerator/titanium_mobile/pull/11830 PR (9.1.x): https://github.com/appcelerator/titanium_mobile/pull/11831Fix has been merged to master, 9_1_X and 9_3_X.
*Closing ticket*. Fix verified in SDK version
9.1.0.v20200724110711
,9.2.0.v20200724112452
and9.3.0.v20200724114100
. Test and other information can be found at: https://github.com/appcelerator/titanium_mobile/pull/11698 PR (master): https://github.com/appcelerator/titanium_mobile/pull/11830 PR (9.1.x): https://github.com/appcelerator/titanium_mobile/pull/11831 *Test Environment*