Culture sensitive ParseFloat Function in JavaScript?
Asked Answered
A

7

11

Do anyone have suggestion for writing culture sensitive ParseFloat Function in JavaScript, So that when I have a string 100,000.22 in US culture format the parse float function returns 100000.22 whereas if I enter 100.000,22 in Swedish Culture it returns 100000.22 in float?

Aili answered 9/2, 2011 at 23:17 Comment(4)
I dont know if this is a culture thing, it is a , thing.Helwig
As I was writing solution for ASP.Net application, I managed to solve my problem without writing any custom solution for it. As MSDN library provide the JavaScript Base Type Extensions method, one of which is Number Type Extensions which has functions localeFormat, and parseLocale. These function provides the conversion from/to decimal format w.r.t culture. see this like msdn.microsoft.com/en-us/library/bb310835(v=VS.90).aspx.Aili
Also one can set the culture from the server otherwise these functions will use the default culture. see this link msdn.microsoft.com/en-us/library/bz9tc508(v=VS.90).aspx. In my case I have to set sv-SE, because I need to use the Swedish culture for formating the numbers.Aili
Possible duplicate of How do I convert String to Number according to locale (opposite of .toLocaleString)?Jiggle
B
6

I've improved mwilcox' function to handle values withous separators.

function parseFloatOpts (str) {

     if(typeof str === "number"){
         return str;
     }

     var ar = str.split(/\.|,/);  

     var value = '';
     for (var i in ar) {
         if (i>0 && i==ar.length-1) {
             value += ".";
         }
         value +=ar[i];
     }
     return Number(value);
}
Baltazar answered 29/11, 2012 at 14:43 Comment(0)
H
3

This is a bit rough-and-ready, but it may be sufficient, allowing you to pass in the thousands and decimal separators:

function parseFloatOpts(num, decimal, thousands) {
    var bits = num.split(decimal, 2),
        ones = bits[0].replace(new RegExp('\\' + thousands, 'g'), '');
        ones = parseFloat(ones, 10),
        decimal = parseFloat('0.' + bits[1], 10);
        return ones + decimal;
}

Examples:

parseFloatOpts("100.000,22", ',', '.'); //100000.22
parseFloatOpts("100,000.22", '.', ','); //100000.22

NB that this doesn't ensure that the thousands separator really does represent thousands, etc., or do lots of other safeguarding that you may wish to do, depending on the importance of the function.

Hausner answered 9/2, 2011 at 23:36 Comment(1)
Thanks for your reply, I am able to solve the problem in ASP.Net. See my above reply in my original post.Aili
S
1
var parse = function(st){
   if(st.indexOf(",") === st.length-3){
      st = st.replace(".", "").replace(",", ".");
   }else{
       st = st.replace(",", "");
   }
   return parseFloat(st, 10)
}

console.log(parse("100,000.22")) // 100000.22
console.log(parse("100.000,22")) // 100000.22

I'm just checking if there is a comma in the 3rd-to-last position. This could be further refined to check if there is a period in the 4th to last position in the case thee is no comma (such as 100.000)

Serna answered 9/2, 2011 at 23:39 Comment(0)
S
1

Looking at lonesomday's gave me this thought:

You could also do:

function parse (str)
    var ar = str.split(/\.|,/);  
    return Number(ar[0]+ar[1]+"."+ar[3]);
Serna answered 9/2, 2011 at 23:44 Comment(1)
How's that going to work for variable numbers of thousands separators?Hausner
H
1

Here is a rough function. It will assume the last punctuation to indicate decimals, whether it is a comma, period, or any other character you may need to indicate. It then eliminates other punctuations from the whole number. Puts it back together and parses as float.

function normalizeFloat(number, chars) {

    var lastIndex = -1;
    for(i=0; i < chars.length; i++) {
        t = number.lastIndexOf(chars[i]);

        if (t > lastIndex) {
            lastIndex = t;
        }
    }

    if (lastIndex == -1) {
        lastIndex = number.length;
    }

    var whole = number.substring(0, lastIndex);   
    var precision = number.substring(lastIndex);
    for (i=0; i < chars.length; i++) {
        whole = whole.replace(chars[i], '');
        precision = precision.replace(chars[i],'.');           
    }
    number = whole + precision;

    f = parseFloat(number);
    return f;
}

try this:

alert(normalizeFloat('12.345,77', [',','.']).toFixed(2));
alert(normalizeFloat('12,345.77', [',','.']).toFixed(2));
Helwig answered 9/2, 2011 at 23:59 Comment(0)
L
0

Need your current Group and Decimal Separator from Culture Info.

function escapeRegExp(string) {
        return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
    }

function parseFloatOpts(str, groupSeparator, decimalSeparator) {

        if (typeof str === "number") {
            return str;
        }

        var value = str.replace(new RegExp(escapeRegExp(groupSeparator), 'g'), "");
        value = value.replace(decimalSeparator, ".");

        return Number(value);
    }
Leventhal answered 5/9, 2019 at 6:7 Comment(0)
H
0

If you really for displaying and/or parsing floats (or dates or currencies or more) in different locales for JavaScript, then my recommendation is the GlobalizeJS (https://github.com/globalizejs/globalize) library.

It's a bit tough to set up at first (at least it was in my experience), but totally recommended for proper management of this matter.

Horten answered 19/2, 2020 at 11:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.