With a browser, how do I know which decimal separator does the operating system use?

后端 未结 13 2078
不思量自难忘°
不思量自难忘° 2020-11-27 17:05

I\'m developing a web application.

I need to display some decimal data correctly so that it can be copied and pasted into a certain GUI application that

相关标签:
13条回答
  • 2020-11-27 17:19

    OK, I have something to show, more a proof of concept than a finished product, but because of lack of precise specifications, I leave it this way (or I will over-engineer it). I post in a separate message because it will be a bit long. I took the opportunity to try a bit more jQuery...

    The Java code: GetLocaleInfo.java

    import java.applet.*;
    import java.util.Locale;
    import java.text.*;
    
    public class GetLocaleInfo extends Applet
    {
      Locale loc;
      NumberFormat nf;
      NumberFormat cnf;
      NumberFormat pnf;
    
      // For running as plain application
      public static void main(String args[])
      {
        final Applet applet = new GetLocaleInfo();
        applet.init();
        applet.start();
      }
    
      public void init() // Applet is loaded
      {
        // Use current locale
        loc = Locale.getDefault();
        nf = NumberFormat.getInstance();
        cnf = NumberFormat.getCurrencyInstance();
        pnf = NumberFormat.getPercentInstance();
      }
    
      public void start() // Applet should start
      {
        // Following output goes to Java console
        System.out.println(GetLocaleInformation());
        System.out.println(nf.format(0.1));
        System.out.println(cnf.format(1.0));
        System.out.println(pnf.format(0.01));
      }
    
      public String GetLocaleInformation()
      {
        return String.format("Locale for %s: country=%s (%s / %s), lang=%s (%s / %s), variant=%s (%s)",
            loc.getDisplayName(),
            loc.getDisplayCountry(),
            loc.getCountry(),
            loc.getISO3Country(),
    
            loc.getDisplayLanguage(),
            loc.getLanguage(),
            loc.getISO3Language(),
    
            loc.getDisplayVariant(),
            loc.getVariant()
        );
      }
    
      public String FormatNumber(String number)
      {
        double value = 0;
        try
        {
          value = Double.parseDouble(number);
        }
        catch (NumberFormatException nfe)
        {
          return "!";
        }
        return nf.format(value);
      }
    
      public String FormatCurrency(String number)
      {
        double value = 0;
        try
        {
          value = Double.parseDouble(number);
        }
        catch (NumberFormatException nfe)
        {
          return "!";
        }
        return cnf.format(value);
      }
    
      public String FormatPercent(String number)
      {
        double value = 0;
        try
        {
          value = Double.parseDouble(number);
        }
        catch (NumberFormatException nfe)
        {
          return "!";
        }
        return pnf.format(value);
      }
    }
    

    An example of HTML page using the above applet: GetLocaleInfo.html

    <!-- Header skipped for brevity -->
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js"></script>
    <script type="text/javascript">
    var applet;
    $(document).ready(function()
    {
      applet = document.getElementById('LocaleInfo');
      $('#Results').text(applet.GetLocaleInformation());
    });
    </script>
    <script type="text/javascript">
    function DoFormatting()
    {
      $('table.toFormat').each(function()
      {
        var table = $(this);
        $('td', table).each(function(cellId)
        {
          var val = $(this);
          if (val.is('.number'))
          {
            val.text(applet.FormatNumber(val.text()));
          }
          else if (val.is('.currency'))
          {
            val.text(applet.FormatCurrency(val.text()));
          }
          else if (val.is('.percent'))
          {
            val.text(applet.FormatPercent(val.text()));
          }
        });
      });
    }
    </script>
    </head>
    <body>
      <div id="Container">
        <p>Page to demonstrate how JavaScript can get locale information from Java</p>
        <div id="AppletContainer">
          <object classid="java:GetLocaleInfo.class"
              type="application/x-java-applet" codetype="application/java"
              name="LocaleInfo" id="LocaleInfo" width="0" height="0">
            <param name="code" value="GetLocaleInfo"/>
            <param name="mayscript" value="true"/>
            <param name="scriptable" value="true"/>
            <p><!-- Displayed if object isn't supported -->
              <strong>This browser does not have Java enabled.</strong>
              <br>
              <a href="http://java.sun.com/products/plugin/downloads/index.html" title="Download Java plug-in">
              Get the latest Java plug-in here
              </a> (or enable Java support).
            </p>
          </object>
        </div><!-- AppletContainer -->
        <p>
        Click on the button to format the table content to the locale rules of the user.
        </p>
        <input type="button" name="DoFormatting" id="DoFormatting" value="Format the table" onclick="javascript:DoFormatting()"/>
        <div id="Results">
        </div><!-- Results -->
    <table class="toFormat">
    <caption>Synthetic View</caption>
    <thead><tr>
    <th>Name</th><th>Value</th><th>Cost</th><th>Discount</th>
    </tr></thead>
    <tbody>
    <tr><td>Foo</td><td class="number">3.1415926</td><td class="currency">21.36</td><td class="percent">0.196</td></tr>
    <tr><td>Bar</td><td class="number">159263.14</td><td class="currency">33</td><td class="percent">0.33</td></tr>
    <tr><td>Baz</td><td class="number">15926</td><td class="currency">12.99</td><td class="percent">0.05</td></tr>
    <tr><td>Doh</td><td class="number">0.01415926</td><td class="currency">5.1</td><td class="percent">0.1</td></tr>
    </tbody>
    </table>
      </div><!-- Container -->
    </body>
    </html>
    

    Tested on Firefox 3.0, IE 6, Safari 3.1 and Opera 9.50, on Windows XP Pro SP3. It works without problem with the first two, on Safari I have a strange error after init() call:

    java.net.MalformedURLException: no protocol:
        at java.net.URL.<init>(Unknown Source)
        at java.net.URL.<init>(Unknown Source)
        at java.net.URL.<init>(Unknown Source)
        at sun.plugin.liveconnect.SecureInvocation.checkLiveConnectCaller(Unknown Source)
        at sun.plugin.liveconnect.SecureInvocation.access$000(Unknown Source)
        at sun.plugin.liveconnect.SecureInvocation$2.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.plugin.liveconnect.SecureInvocation.CallMethod(Unknown Source)
    

    but it still works.

    I can't get it work with Opera: the applet loads correctly, as I can see the trace of init() call in the Java console, I have no errors when JavaScript calls the Java functions (except if I add and call a method getting a JSObject parameter, curiously), but the Java functions are not called (I added trace of the calls).
    I believe Liveconnect works in Opera, but I don't see yet how. I will research a bit more.
    [Update] I removed references to non-existing jar file (which doesn't stop other browsers) and I got a trace of the calls, but it doesn't update the page.
    Mmm, if I do alert(applet.GetLocaleInformation()); I got the information, so it might be a jQuery issue.

    0 讨论(0)
  • 2020-11-27 17:22

    Using other people answers I compiled the following decimal and thousand separators utility functions:

    var decimalSeparator = function() {
        return (1.1).toLocaleString().substring(1, 2);
    };
    var thousandSeparator = function() {
        return (1000).toLocaleString().substring(1, 2);
    };
    

    Enjoy!

    0 讨论(0)
  • 2020-11-27 17:23

    Similar to other answers, but compressed as a constant:

    const decimal=.1.toLocaleString().substr(1,1);      //returns "." in Canada
    

    Also, to get the thousands separator:

    const thousands=1234..toLocaleString().substr(1,1);   //returns "," in Canada
    

    Just place the code at the top of your JS and then call as required to return the symbol.


    For example (where I live), to remove commas from "1,234,567":

    console.log( "1,234,567".replaceAll(thousands,"") ); //prints "1234567" to console.  
    
    0 讨论(0)
  • 2020-11-27 17:27
    function getDecimalSeparator() {
        //fallback  
           var decSep = ".";
    
            try {
                // this works in FF, Chrome, IE, Safari and Opera
                var sep = parseFloat(3/2).toLocaleString().substring(1,2);
                if (sep === '.' || sep === ',') {
                    decSep = sep;
                }
            } catch(e){}
    
            return decSep;
        }
    
    0 讨论(0)
  • 2020-11-27 17:33

    Retrieving separators for the current or a given locale is possible using Intl.NumberFormat#formatToParts.

    function getDecimalSeparator(locale) {
        const numberWithDecimalSeparator = 1.1;
        return Intl.NumberFormat(locale)
            .formatToParts(numberWithDecimalSeparator)
            .find(part => part.type === 'decimal')
            .value;
    }
    

    It only works for browsers supporting the Intl API. Otherwise it requires an Intl polyfill

    Examples:

    > getDecimalSeparator()
    "."
    > getDecimalSeparator('fr-FR')
    ","
    

    Bonus:

    We could extend it to retrieve either the decimal or group separator of a given locale:

    function getSeparator(locale, separatorType) {
            const numberWithGroupAndDecimalSeparator = 1000.1;
            return Intl.NumberFormat(locale)
                .formatToParts(numberWithGroupAndDecimalSeparator)
                .find(part => part.type === separatorType)
                .value;
        }
    

    Examples:

    > getSeparator('en-US', 'decimal')
    "."
    > getSeparator('en-US', 'group')
    ","
    > getSeparator('fr-FR', 'decimal')
    ","
    > getSeparator('fr-FR', 'group')
    " "
    
    0 讨论(0)
  • 2020-11-27 17:35

    "Is there any way to do it on server side (preferably, so that I can collect statistics), or on client side?"

    No you can't. That GUI is looking at some user or machine specific settings. First, you probably do not know at what settings this UI is looking. Second, with a webapplication you will probably not be able to check these settings (clientside --> Javacsript).

    0 讨论(0)
提交回复
热议问题