Locale aware number conversion in JavaScript

后端 未结 2 1113
误落风尘
误落风尘 2020-12-16 23:18

Is there a JQuery Plugin available that facilitates NUMBER LOCALIZATION ? That is , the plugin should translate numerals

相关标签:
2条回答
  • 2020-12-17 00:00

    I think your best bet is the jQuery Globalize plugin: https://github.com/jquery/globalize

    0 讨论(0)
  • 2020-12-17 00:05

    You could use a simple function like this one for the translation from Arabic numerals:

    function translateNumerals(input, target) {
        var systems = {
                devanagari: 2406, tamil: 3046, kannada:  3302, 
                telugu: 3174, marathi: 2406, malayalam: 3430, 
                oriya: 2918, gurmukhi: 2662, nagari: 2534, gujarati: 2790
            },
            zero = 48, // char code for Arabic zero
            nine = 57, // char code for Arabic nine
            offset = (systems[target.toLowerCase()] || zero) - zero,
            output = input.toString().split(""),
            i, l = output.length, cc;
    
        for (i = 0; i < l; i++) {
            cc = output[i].charCodeAt(0);
            if (cc >= zero && cc <= nine) {
                output[i] = String.fromCharCode(cc + offset);
            }
        }
        return output.join("");
    }
    

    And call it like this

    translateNumerals(12345, "Telugu")      // "౧౨౩౪౫"
    translateNumerals(12345, "Devanagari")  // "१२३४५"
    translateNumerals("foo", "Devanagari")  // "foo"
    

    The translation to Arabic numerals is equally simple. It requires just a little more plumbing.

    The above function knows the charCode of the Zero in any target system and does some simple math to do a character-by-character conversion from Arabic numerals to that system.

    A reverse function would need to check each character of the input. If it falls the charCode range of any source system (i.e. the charCode of the respective Zero + 9) it knows the required offset. Subtracting the offset will get you into the Arabic range. This is pretty trivial and I'll leave it to you.


    EDIT #1: Since you mentioned jQuery, the above could be made into a plugin like this:

    jQuery.fn.extend({
        textTranslateNumerals: (function () {
            var translateNumerals = function (input, target) {
                // the above function
            };
            return function (target) {
                // for each selected element...
                return this.each(function () {
                    // ...look at each child node and
                    $(this).contents().each(function () {
                        // ...translate text nodes, recurse into elements
                        if (this.nodeType === this.TEXT_NODE) {
                            $(this).text(translateNumerals($(this).text(), target));
                        } else if (this.nodeType === this.ELEMENT_NODE) {
                            $(this).textTranslateNumerals(target);
                        }
                    });
                });
            };
        })()
    });
    

    EDIT #2: FWIW, here is a function that can convert from any source system into any target system:

    function translateNumerals(input, source, target) {
      var systems = {
        arabic:       48,
        devanagari: 2406, tamil: 3046, kannada:  3302, telugu: 3174, marathi:  2406,
        malayalam:  3430, oriya: 2918, gurmukhi: 2662, nagari: 2534, gujarati: 2790,
      },
      output = [], offset = 0, zero = 0, nine = 0, char = 0;
    
      source = source.toLowerCase();
      target = target.toLowerCase();
    
      if ( !(source in systems && target in systems) 
           || input == null 
           || typeof input == "undefined" || typeof input == "object" ) {
        return input;
      }
    
      input  = input.toString();
      offset = systems[target] - systems[source];
      zero   = systems[source];
      nine   = systems[source] + 9;
    
      for (var i=0, l=input.length; i<l; i++) {
        var char = input.charCodeAt(i);
    
        if (char >= zero && char <= nine) {
          output.push( String.fromCharCode(char + offset) );
        } else {
          output.push( input[i] );
        }
      }
      return output.join("");
    }
    

    Sample outputs

    translateNumerals("0123456789", "arabic", "malayalam")  // "൦൧൨൩൪൫൬൭൮൯"
    translateNumerals("൦൧൨൩൪൫൬൭൮൯", "malayalam", "arabic")  // "0123456789"
    translateNumerals("൦൧൨൩൪൫൬൭൮൯", "malayalam", "kannada") // "೦೧೨೩೪೫೬೭೮೯"
    translateNumerals("೦೧೨೩೪೫೬೭೮೯", "kannada", "nagari") // "০১২৩৪৫৬৭৮৯"
    translateNumerals("೦೧೨೩೪೫೬೭೮೯", "kannada", "gujarati") // "૦૧૨૩૪૫૬૭૮૯"
    translateNumerals("USD 13.56", "arabic", "nagari") // "USD ১৩.৫৬"
    
    0 讨论(0)
提交回复
热议问题