{ "id": "173876", "key": "TIMOB-27240", "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-07-19T14:16:28.000+0000", "created": "2019-07-12T18:31:32.000+0000", "priority": { "name": "Medium", "id": "3" }, "labels": [ "Intl", "NumberFormat", "android", "format", "locale", "localization", "parity" ], "versions": [], "issuelinks": [ { "id": "57735", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "outwardIssue": { "id": "173051", "key": "TIMOB-26858", "fields": { "summary": "Android (V8): toLocaleDateString has different outputs on iOS and Android", "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" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } }, { "id": "58359", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "outwardIssue": { "id": "175000", "key": "TIMOB-27890", "fields": { "summary": "Android: Add Intl.DateTimeFormat support", "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" } }, "priority": { "name": "Medium", "id": "3" }, "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false } } } }, { "id": "58361", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "175001", "key": "TIMOB-27891", "fields": { "summary": "Android: Add Intl.Collator support", "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" } }, "priority": { "name": "Medium", "id": "3" }, "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false } } } }, { "id": "58363", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "175002", "key": "TIMOB-27892", "fields": { "summary": "Android: Update toLocale*String() methods to support locale/options", "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" } }, "priority": { "name": "Medium", "id": "3" }, "issuetype": { "id": "4", "description": "An improvement or enhancement to an existing feature or task.", "name": "Improvement", "subtask": false } } } } ], "assignee": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2020-07-30T13:04:57.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" } ], "description": "We use the {{Intl.NumberFormat}} class to format currencies, e.g.:\r\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat\r\n{code:js}\r\nconst value = new Intl.NumberFormat('en-US', {\r\n style: 'currency',\r\n currency: 'USD',\r\n minimumFractionDigits: 2\r\n}).format(10.12);\r\n\r\nconsole.log(value); // output: $10.12\r\n{code}\r\nIt 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].\r\n\r\nWorkaround until then is writing another native module:\r\n{code:java}\r\n\r\n@Kroll.module(name=\"TiCurrency\", id=\"ti.currency\")\r\npublic class TiCurrencyModule extends KrollModule\r\n{\r\n\tprivate static final String LCAT = \"TiCurrencyModule\";\r\n\tprivate static final boolean DBG = TiConfig.LOGD;\r\n\r\n\t@Kroll.method\r\n\tpublic String format(KrollDict params)\r\n\t{\r\n\t\tdouble value = params.getDouble(\"value\");\r\n\t\tString currency = params.getString(\"currency\");\r\n\r\n\t\tNumberFormat format = NumberFormat.getCurrencyInstance(Locale.getDefault());\r\n\t\tformat.setCurrency(Currency.getInstance(currency));\r\n\r\n\t\treturn format.format(value);\r\n\t}\r\n}\r\n{code}", "attachment": [], "flagged": false, "summary": "Android: Add Intl.NumberFormat support", "creator": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "subtasks": [], "reporter": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "environment": null, "closedSprints": [ { "id": 1201, "state": "closed", "name": "2020 Sprint 14", "startDate": "2020-07-06T15:40:00.000Z", "endDate": "2020-07-17T15:40:00.000Z", "completeDate": "2020-07-20T22:16:28.367Z", "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": "449776", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Hmm... it looks like this is an optional feature that we have to #define-in via \"V8_INTL_SUPPORT\".\r\nhttps://github.com/v8/v8/search?q=V8_INTL_SUPPORT&unscoped_q=V8_INTL_SUPPORT\r\n\r\nAlthough 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.\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-07-12T21:34:39.000+0000", "updated": "2019-07-12T21:34:39.000+0000" }, { "id": "449777", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Same goes for {{toLocaleDateString}} btw. Having those cross platform would really be a benefit.", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2019-07-12T21:47:48.000+0000", "updated": "2019-07-12T21:47:48.000+0000" }, { "id": "449778", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Yes, I agree. Thanks for bringing this up.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-07-12T21:51:05.000+0000", "updated": "2019-07-12T21:51:05.000+0000" }, { "id": "455406", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "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.\r\n\r\nI think the best solution is for us to implement {{NumberFormat}} support on the Java side.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-05-08T18:22:38.000+0000", "updated": "2020-05-08T18:22:38.000+0000" }, { "id": "455419", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "PR (master): https://github.com/appcelerator/titanium_mobile/pull/11698", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-05-09T04:26:14.000+0000", "updated": "2020-05-09T04:26:14.000+0000" }, { "id": "456152", "author": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "body": "manually rebase/merged to master, 9_1_X, 9_3_X", "updateAuthor": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "created": "2020-07-19T14:16:28.000+0000", "updated": "2020-07-19T14:16:28.000+0000" }, { "id": "456178", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "There's a bug with {{formatToParts()}} on Android 4.4. Fixed via PRs...\r\n\r\nPR (master): https://github.com/appcelerator/titanium_mobile/pull/11830\r\nPR (9.1.x): https://github.com/appcelerator/titanium_mobile/pull/11831\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-07-21T02:55:07.000+0000", "updated": "2020-07-21T02:55:30.000+0000" }, { "id": "456186", "author": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "body": "Fix has been merged to master, 9_1_X and 9_3_X.", "updateAuthor": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "created": "2020-07-21T14:18:04.000+0000", "updated": "2020-07-21T14:18:04.000+0000" }, { "id": "456288", "author": { "name": "smohammed", "key": "smohammed", "displayName": "Samir Mohammed", "active": true, "timeZone": "America/Los_Angeles" }, "body": "*Closing ticket*. Fix verified in SDK version {{9.1.0.v20200724110711}}, {{9.2.0.v20200724112452}} and {{9.3.0.v20200724114100}}.\r\n\r\nTest and other information can be found at:\r\nhttps://github.com/appcelerator/titanium_mobile/pull/11698\r\nPR (master): https://github.com/appcelerator/titanium_mobile/pull/11830\r\nPR (9.1.x): https://github.com/appcelerator/titanium_mobile/pull/11831\r\n\r\n*Test Environment*\r\n{code:java}\r\nMacOS Big Sur: 11.0 Beta\r\nXcode: 12.0 Beta \r\nJava Version: 1.8.0_242\r\nAndroid NDK: 21.3.6528147\r\nNode.js: 12.18.1\r\n\"\"NPM\":\"5.0.0\",\"CLI\":\"8.1.0-master.5\"\"\r\nAPI19 Nexus5X\r\nAPI29 Pixel XL emulator\r\n{code}\r\n", "updateAuthor": { "name": "smohammed", "key": "smohammed", "displayName": "Samir Mohammed", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-07-30T13:01:53.000+0000", "updated": "2020-07-30T13:04:00.000+0000" } ], "maxResults": 9, "total": 9, "startAt": 0 } } }