Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-27874] TiAPI: Add Ti.Locale.parseDecimal() method

GitHub Issuen/a
TypeNew Feature
PriorityMedium
StatusClosed
ResolutionFixed
Resolution Date2020-08-07T10:46:11.000+0000
Affected Version/sn/a
Fix Version/sRelease 9.1.0
ComponentsAndroid, iOS
Labelsandroid, decimal, ios, locale, parse
ReporterJoshua Quick
AssigneeJoshua Quick
Created2020-04-30T05:33:30.000+0000
Updated2020-08-07T10:46:11.000+0000

Description

*Summary:* Titanium has APIs to turn numbers into localized strings, but there are no APIs to convert a localized numeric string back to a number type. *Proposed Solution:* Add the following method. Ti.Locale.parseDecimal(text \[, locale \]); // Returns number type. If the above was given an invalid string, then it will return NaN (Not-a-Number), which matches JavaScript's standard Number.parseFloat() method behavior. *Main Use-Case:* A TextField using a decimal keyboard type will be using the device's current locale for the decimal separator. This means the decimal separator will be a comma , in Europe. It will can also be a unicode decimal separator for Arabic locales. When reading the TextField string "value" property, the app developer will need an easy means of parsing the localized numeric string back to a JS number type. *Test Cases:* Converting a number to localized string and then back to a number.
var oldNumericValue = 123.456;
var stringValue = String.formatDecimal(oldNumericValue);
var newNumericValue = Ti.Locale.parseDecimal(stringValue);
if (Math.abs(newNumericValue - oldNumericValue) < Number.EPSILON) {
 	console.log('Parsed number matches original number.');
}
Parsing equivalent numbers from 2 different locales.
var number1 = Ti.Locale.parseDecimal('1,234,567.8', 'en-US');
var number2 = Ti.Locale.parseDecimal('1.234.567,8', 'de-DE');
if (Math.abs(number1 - number2) < Number.EPSILON) {
	console.log('Parsed numbers match.');
}
Strings that cannot be converted to a number will return NaN.
var result = Ti.Locale.parseDecimal('Invalid');
if (Number.isNaN(result)) {
	console.log('Invalid string returned NaN.');
}

Comments

  1. Ewan Harris 2020-04-30

    What would the relation be to the Intl APIs for NumberFormat (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat), I believe we don't polyfill Intl right now (core-js skips it due to the size of it), but I think we should deal with this in a spec'd manner rather than our own APIs Edit: Ignore this comment, I totally misread the intention here
  2. Joshua Quick 2020-04-30

    [~eharris], I'm pretty sure we do support the Intl APIs on iOS, but we definitely don't on Android. If we were to #if it into V8, then it would add a huge 20 MB ICU (International Components for Unicode) library for just a single architecture... and we would need to include at least 2 architectures. This is not mobile friendly. Especially since the max APK size you can upload to Google Play is 100 MB. I didn't see any official JS APIs that support parsing localized numeric strings, so, I came up with the above. I named them similar to the existing toLocaleString(), toLocaleTimeString(), toLocaleDateString(), etc. Although it turns out those APIs on Android ignore the current locale and only do the default "en-us" locale. (That should be a separate ticket. We have to localize the strings ourselves on the Java side since Android NDK does not support locale on the C/C++ side.)
  3. Joshua Quick 2020-04-30

    Maybe instead of extending the Number type and risking future collisions, we should add these APIs to our Ti.Locale module instead.
  4. Joshua Quick 2020-05-05

    PR (master): https://github.com/appcelerator/titanium_mobile/pull/11683
  5. Samir Mohammed 2020-07-09

    FR Passed, Waiting on Jenkins build.
  6. Christopher Williams 2020-07-13

    merged to master for 9.1.0 target
  7. Joshua Quick 2020-07-15

    Below PR improves handling for locales that use whitespace chars for thousands separator like French. PR (master): https://github.com/appcelerator/titanium_mobile/pull/11824
  8. Sohail Saddique 2020-08-07

    Fix verified on build 9.1.0.v20200804082025. Ticket closed.

JSON Source