{ "id": "174972", "key": "TIMOB-27874", "fields": { "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "20950", "name": "Release 9.1.0", "archived": false, "released": true, "releaseDate": "2020-08-25" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2020-08-07T10:46:11.000+0000", "created": "2020-04-30T05:33:30.000+0000", "priority": { "name": "Medium", "id": "3" }, "labels": [ "android", "decimal", "ios", "locale", "parse" ], "versions": [], "issuelinks": [], "assignee": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2020-08-07T10:46:11.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" }, { "id": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "*Summary:*\r\nTitanium has APIs to turn numbers into localized strings, but there are no APIs to convert a localized numeric string back to a number type.\r\n\r\n*Proposed Solution:*\r\nAdd the following method.\r\n{{Ti.Locale.parseDecimal(text \\[, locale \\]); // Returns number type.}}\r\n\r\nIf the above was given an invalid string, then it will return {{NaN}} (Not-a-Number), which matches JavaScript's standard {{Number.parseFloat()}} method behavior.\r\n\r\n*Main Use-Case:*\r\nA {{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.\r\n\r\n*Test Cases:*\r\nConverting a number to localized string and then back to a number.\r\n{code:javascript}\r\nvar oldNumericValue = 123.456;\r\nvar stringValue = String.formatDecimal(oldNumericValue);\r\nvar newNumericValue = Ti.Locale.parseDecimal(stringValue);\r\nif (Math.abs(newNumericValue - oldNumericValue) < Number.EPSILON) {\r\n \tconsole.log('Parsed number matches original number.');\r\n}\r\n{code}\r\n\r\nParsing equivalent numbers from 2 different locales.\r\n{code:javascript}\r\nvar number1 = Ti.Locale.parseDecimal('1,234,567.8', 'en-US');\r\nvar number2 = Ti.Locale.parseDecimal('1.234.567,8', 'de-DE');\r\nif (Math.abs(number1 - number2) < Number.EPSILON) {\r\n\tconsole.log('Parsed numbers match.');\r\n}\r\n{code}\r\n\r\nStrings that cannot be converted to a number will return NaN.\r\n{code:javascript}\r\nvar result = Ti.Locale.parseDecimal('Invalid');\r\nif (Number.isNaN(result)) {\r\n\tconsole.log('Invalid string returned NaN.');\r\n}\r\n{code}\r\n", "attachment": [], "flagged": false, "summary": "TiAPI: Add Ti.Locale.parseDecimal() method", "creator": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "environment": null, "closedSprints": [ { "id": 1194, "state": "closed", "name": "2020 Sprint 9", "startDate": "2020-04-24T17:09:51.572Z", "endDate": "2020-05-08T17:09:00.000Z", "completeDate": "2020-05-08T15:40:07.869Z", "originBoardId": 114 }, { "id": 1195, "state": "closed", "name": "2020 Sprint 10", "startDate": "2020-05-08T16:37:58.282Z", "endDate": "2020-05-22T16:37:00.000Z", "completeDate": "2020-05-21T15:26:11.089Z", "originBoardId": 114 }, { "id": 1196, "state": "closed", "name": "2020 Sprint 11", "startDate": "2020-05-26T15:56:00.000Z", "endDate": "2020-06-05T15:56:00.000Z", "completeDate": "2020-06-08T21:05:50.356Z", "originBoardId": 114 }, { "id": 1198, "state": "closed", "name": "2020 Sprint 12", "startDate": "2020-06-08T21:06:41.849Z", "endDate": "2020-06-19T21:06:00.000Z", "completeDate": "2020-06-19T15:54:38.493Z", "originBoardId": 114 }, { "id": 1199, "state": "closed", "name": "2020 Sprint 13", "startDate": "2020-06-19T16:41:04.099Z", "endDate": "2020-07-02T16:41:00.000Z", "completeDate": "2020-07-02T15:37:12.455Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "455312", "author": { "name": "eharris", "key": "eharris", "displayName": "Ewan Harris", "active": true, "timeZone": "Europe/Dublin" }, "body": "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\r\n\r\nEdit:\r\n\r\nIgnore this comment, I totally misread the intention here", "updateAuthor": { "name": "eharris", "key": "eharris", "displayName": "Ewan Harris", "active": true, "timeZone": "Europe/Dublin" }, "created": "2020-04-30T12:09:00.000+0000", "updated": "2020-04-30T16:31:22.000+0000" }, { "id": "455313", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~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.\r\n\r\nI 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.)\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-04-30T16:07:54.000+0000", "updated": "2020-04-30T16:07:54.000+0000" }, { "id": "455314", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Maybe instead of extending the {{Number}} type and risking future collisions, we should add these APIs to our {{Ti.Locale}} module instead.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-04-30T16:40:17.000+0000", "updated": "2020-04-30T16:40:17.000+0000" }, { "id": "455352", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "PR (master): https://github.com/appcelerator/titanium_mobile/pull/11683", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-05-05T00:15:38.000+0000", "updated": "2020-05-05T00:15:38.000+0000" }, { "id": "456030", "author": { "name": "smohammed", "key": "smohammed", "displayName": "Samir Mohammed", "active": true, "timeZone": "America/Los_Angeles" }, "body": "FR Passed, Waiting on Jenkins build. ", "updateAuthor": { "name": "smohammed", "key": "smohammed", "displayName": "Samir Mohammed", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-07-09T15:05:11.000+0000", "updated": "2020-07-09T15:05:11.000+0000" }, { "id": "456066", "author": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "body": "merged to master for 9.1.0 target", "updateAuthor": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "created": "2020-07-13T20:08:37.000+0000", "updated": "2020-07-13T20:08:37.000+0000" }, { "id": "456115", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Below PR improves handling for locales that use whitespace chars for thousands separator like French.\r\n\r\nPR (master): https://github.com/appcelerator/titanium_mobile/pull/11824\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-07-15T23:18:08.000+0000", "updated": "2020-07-15T23:18:08.000+0000" }, { "id": "456370", "author": { "name": "ssaddique", "key": "ssaddique", "displayName": "Sohail Saddique", "active": true, "timeZone": "Europe/London" }, "body": "Fix verified on build 9.1.0.v20200804082025. Ticket closed.", "updateAuthor": { "name": "ssaddique", "key": "ssaddique", "displayName": "Sohail Saddique", "active": true, "timeZone": "Europe/London" }, "created": "2020-08-07T10:45:50.000+0000", "updated": "2020-08-07T10:45:50.000+0000" } ], "maxResults": 8, "total": 8, "startAt": 0 } } }