Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-27240] Android: Add Intl.NumberFormat support

GitHub Issuen/a
TypeNew Feature
PriorityMedium
StatusClosed
ResolutionFixed
Resolution Date2020-07-19T14:16:28.000+0000
Affected Version/sn/a
Fix Version/sRelease 9.1.0
ComponentsAndroid
LabelsIntl, NumberFormat, android, format, locale, localization, parity
ReporterHans Knöchel
AssigneeJoshua Quick
Created2019-07-12T18:31:32.000+0000
Updated2020-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);
	}
}

Comments

  1. Joshua Quick 2019-07-12

    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.
  2. Hans Knöchel 2019-07-12

    Same goes for toLocaleDateString btw. Having those cross platform would really be a benefit.
  3. Joshua Quick 2019-07-12

    Yes, I agree. Thanks for bringing this up.
  4. Joshua Quick 2020-05-08

    I've looked into this. If we were to #if-in JS Intl 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 implement NumberFormat support on the Java side.
  5. Joshua Quick 2020-05-09

    PR (master): https://github.com/appcelerator/titanium_mobile/pull/11698
  6. Christopher Williams 2020-07-19

    manually rebase/merged to master, 9_1_X, 9_3_X
  7. Joshua Quick 2020-07-21

    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/11831
  8. Christopher Williams 2020-07-21

    Fix has been merged to master, 9_1_X and 9_3_X.
  9. Samir Mohammed 2020-07-30

    *Closing ticket*. Fix verified in SDK version 9.1.0.v20200724110711, 9.2.0.v20200724112452 and 9.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*
       MacOS Big Sur: 11.0 Beta
       Xcode: 12.0 Beta 
       Java Version: 1.8.0_242
       Android NDK: 21.3.6528147
       Node.js: 12.18.1
       ""NPM":"5.0.0","CLI":"8.1.0-master.5""
       API19 Nexus5X
       API29 Pixel XL emulator
       

JSON Source