New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Currency formatting is wrong with RTL layout and dollar sign #20394
Comments
FWIW as a native Hebrew speaker placing the sign on either side "feels" reasonable to me. So at least for the Hebrew formatting I think we should keep it as-is (sign is to the left of the digits). |
There needs to be a standard answer for each language. Otherwise our charts end up displaying the formatted String one way, the Flutter text block ends up displaying it another way, and the UI looks inconsistent. Then people start filing bugs. For reference, I believe the CDLR is what the Dart NumberFormat class ultimately relies on. FWIW the Hebrew version isn't giving us any trouble. (I think because in Hebrew, NumberFormat does not put a space between the $-sign and the amount, so the order doesn't get flipped) |
This seems like a problem with |
(Assuming I'm right, that means that short-term the answer is probably to put TextDirection.ltr on the text span.) |
This doesn't really specify very well what was done, but assuming that the locale is plain "ar", the code that's listed looks like So Intl does not insert any BiDi markers in the text. The surrounding context might auto-detect it, and generally seems to in web browsers, but might not in others. It sounds like Flutter might not autodetect it at all, or might autodetect it for the letters, but that the space in between resets the direction, even for a non-breaking space? |
Note that there are a number of useful Bidi-related methods in Intl which might be helpful. I really haven't used them in practice much, but https://github.com/dart-lang/intl/blob/1771fd26af88dd4b22c3c177fd8e86ad37fcc56e/lib/src/intl/bidi_formatter.dart#L130 might be useful if you want to automatically wrap a formatted number in RTL when it looks like it contains RTL text. Or https://github.com/dart-lang/intl/blob/1771fd26af88dd4b22c3c177fd8e86ad37fcc56e/lib/src/intl/bidi_utils.dart#L166 to check on a per-locale basis |
The question is what is the context that that format assumes? Does it assume that that string will be rendered with the paragraph directionality set to RTL or LTR? |
Since the data does not indicate, I would think the assumption is that it will be rendered according to the conventions of the thing that is displaying it. But I'm not a domain expert, and we're just trying to do the same thing as ICU/CLDR for numbers. Does Flutter attempt to detect and render RTL strings appropriately? |
You can't really "detect" RTL, you have to know ahead of time what the directionality is. We do support that (so if you're in an arabic localization, e.g., everything will be RTL). |
In a RTL rendering of the number formatted for a RTL locale, I would expect the number to be formatted correctly. The numeric format for "ar" has the currency symbol before the number, i.e. I would expect it to be on the right in RTL. According to Unicode, these are the correct formats for Arabic. http://www.unicode.org/cldr/charts/latest/verify/numbers/ar.html However, I find it very peculiar that in that chart the currency symbol is on the left when we're not compacting the numbers, but switches to the right when we do compact. The chart has an explicit RTL marker around the compact values, but not the regular ones. |
Based on that page and on http://www.unicode.org/cldr/charts/latest/verify/numbers/he.html, it looks to me like the description in the first comment here is what is expected. |
So, in a web browser, the behavior appears to be as follows. In a RTL context. Numbers with Arabic words after them are rendered RTL. I don't know how this compares to Flutter behavior. It sounds consistent with what's described except for the last one. I don't know if "squiggle" is intended to mean that it rendered correctly RTL, or if it means that it was rendered RTL but the Arabic characters were garbled. I tried out AdWords in an "ar" locale, to see what they're doing, and I noticed that in one place they had "$1.23", which renders LTR because they didn't format it to locale conventions, omitting the space. In most other places that had non-compacted currency amounts they wrote "US$ 1.23". This does seem rather awkward to use. The information we produce is identical to ICU. It's not clear to me if there's a recommended way to use this in order to get the correct renderings. I also notice that in the Unicode chart above there is no space between the currency symbol and the number, which does not seem to be consistent with the data. |
Flutter appears to behave more or less like the browser. When wrapped in
r'$ 3' renders LTR So it may not be possible to detect orientation, but something seems to be trying. Since this is the same as the browser it may be a feature rather than a bug. |
I've received confirmation that the CLDR is designed so that the formatting for RTL locales will work correctly when rendered with the right directionality for that locale. That means that what is described in the first comment is correct behaviour, and there's no bug here. I'm going to close this issue. Please don't hesitate to file a new bug if you find another potential error in the localizing. Thanks! |
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of |
Posting on behalf of mulligan:
When formatting currency values in RTL (Arabic), the formatted values are getting reordered in unexpected ways.
$ 100.50 (Arabic) is displayed as 100.50 $ (incorrect?)
SR 100.50 (Arabic, Saudi Riyals) is displayed as SR 100.50 (correct?)
$100.50 (Hebrew) is displayed as $100.50 (correct?)
$ 2.57 ألف (Arabic, $2.57K) is displayed as squiggle 2.57 $ (¯_(ツ)_/¯)
Note that we are using
NumberFormat.compactFormatCurrency()
which does generally localize numbers properly.Adding
textDirection: TextDirection.ltr,
seems to generally fix things, but also seems like the wrong solution. It looks like maybe the standalone dollar sign symbol is getting treated specially and moved about in ways that regular letters aren't when the text direction is RTL?Here is a simplified snippet of our code:
Blockquote
new Text(
new NumberFormat.compactSimpleCurrency(name: 'USD').format(257000))
)
Blockquote
The text was updated successfully, but these errors were encountered: