Answered Trouble in parsing AE currency price to double value

Palak Shah

Well-known member
Joined
Apr 29, 2020
Messages
97
Programming Experience
1-3
I have one function which parses the string text to double value and it works for almost all cultures except UAE

Code

Function:
public static double Parse(string text, string culture)
        {
              
                return double.Parse(text.Replace(" ", ""), NumberStyles.AllowCurrencySymbol | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands,
                   new CultureInfo(culture));
        }


Value for UAE which has issue: "د.إ. 259.00"

Culture code: "ar-AE"

Exception Getting: System.FormatException: 'Input string was not in a correct format.'
 
Monetary values should be put into decimal instead of double. This will cut down dramatically on rounding errors when your deal with values.
 
Okay, but I just get confused in one part, all other culture works fine in parsing but only for AE it just doesn't work

1596117598434.png
 
Do not post screenshots of code. Paste your code. We can't copy code from a screenshot and I certainly won't be writing it off a screenshot, so make our lives a bit easier and stop screenshotting code.
 
It doesn't matter if you've already posted it above. Just don't post screenshots of your code please. It takes up unnecessary space on the screen. And it's not very useful at all. If you're going to post code, then post it as code and put it in code tags provided by the forum editor.
 
Cross post: Facing issue in uae currency code price to double in c#
"The issue is that the currency symbol in the currency contains a RIGHT-TO-LEFT MARK as its last character." ... while your string is missing this char.
I tried below case, but still getting exception


C#:
public static double Parse(string text, string culture)
        {
            if (culture.Contains("AE"))
            {
                var righttoleft = ((Char)0x200F);
                text = text + (righttoleft);
                
            }
            if (text.ToLower().Equals("free"))
                return 0;
            else   
                return double.Parse(text.Replace(" ", ""), NumberStyles.AllowCurrencySymbol | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands,
                   new CultureInfo(culture));
        }
 
Left to Right changes the order of the characters, appending RLM char doesn't fix that string. Your best bet is to get rid of the partly currency symbol before parsing the number.
 
Me and Skydiver had a great discussion on RTL LTR on this topic but it looks like some pages are missing form the topic problem with concatenating number with hebrew

I concur. Drop the symbol and concatenate it later if need be. Hebrew and Arabic will cause all kinds of issues as outlined in the topic linked. Pass the value without the symbol and once parsed, concatenate or use join to add it back later when updating your view.
 
While this doesn't fix your issue, instead its more of a splitting of your values, and a work around to save your sanity. Because working with Arabic or Hebrew in C# is difficult, as there are vowels and such which can slip through any filters for certain characters etc. This is not meant to be taken as is. Edit it to your liking and taste. The Tuple values allow for fast transient data flow so they won't effect performance. I suggest breaking the code down into smaller functions. Such as checking if currency is Hebrew or Arabic, and remove the currency symbols by segregating them in a string array from an additional function, because ultimately, all you need to do is parse the double right?

Also be careful with that Parse, because if it does not parse, it will throw and exception, so consider adding a try catch block and handle the response in the catch section if there is an error. Some quick example code :
C#:
        private void Button1_Click(object sender, RoutedEventArgs e)
        {
            if (IsCultureARAE("ar-AE"))
            {
                Tuple<double, string, string> parse_Result = ParseArabic(new string[] { "259.00", "د.إ", "" }, "ar-AE");
                Debug.WriteLine($"Item one is your double value : {parse_Result.Item1} - Item two is your Currency : {parse_Result.Item2} - Item three is your price with symbol aligned RLM : {parse_Result.Item3}");
            }
        }
        public bool IsCultureARAE(string culture)
        {
            return culture.Contains("AE");
        }
        const string LRM = "\u200E";
        const string RLM = "\u200F";
        public Tuple<double, string, string> ParseArabic(string[] text, string culture)
        {
            text[2] = string.Join(" ", RLM + text[0], text[1]);
            return text[0].Equals("free", StringComparison.CurrentCultureIgnoreCase)
                ? Tuple.Create(0.0, text[1], text[2])
                : Tuple.Create(double.Parse(text[0], NumberStyles.AllowCurrencySymbol | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands,
                   new CultureInfo(culture)), text[1], text[2]);
        }
 
Woohoo! I got it to work!
C#:
var culture = new CultureInfo("ar-AE");
var value = 259.00m;

var s = value.ToString("C", culture);
MessageBox.Show(s);

var flags = NumberStyles.AllowCurrencySymbol |
            NumberStyles.AllowDecimalPoint |
            NumberStyles.AllowThousands |
            NumberStyles.AllowLeadingWhite |
            NumberStyles.AllowTrailingWhite;
var v = decimal.Parse(s, flags, culture);
MessageBox.Show(v.ToString("C", culture));

The magic are in lines 10-11.
 
Woohoo! I got it to work!
No, OP's problem is that the currency symbol in input is incorrect.

However, when currency symbol is correct AllowTrailingWhite does work without having to remove the space.
 
Last edited:
Back
Top Bottom