In the browser, how do I know which decimal separator the client is using?

I am developing a web application.

I need to display some decimal data correctly so that it can be copied and pasted into a specific GUI application that is not under my control.

The GUI application is locale sensitive and accepts only the correct decimal separator that is installed on the system.

I can guess the decimal separator from Accept-Language , and the assumption will be correct in 95% of cases, but sometimes it fails.

Is there a way to do this on the server side (preferably so I can collect statistics) or on the client side?

Update:

The entire task task is performed automatically.

In fact, this webapp is a kind of interactive interface to an outdated graphical interface that helps fill out forms correctly.

The types of users who use it basically do not know what a decimal separator is.

Accept-Language solution is implemented and working, but I would like to improve it.

Update2:

I need to get a very specific parameter: the decimal separator is set to Control Panel / Regional and Language Options / Regional Options / Customize .

I deal with four kinds of operating systems:

  • Russian Windows with a comma as DS (80%).
  • English Windows with a DS period (15%).
  • Russian Windows with a DS period for poorly written English applications (4%).
  • Russian Windows with a comma as DS for working poorly written Russian applications (1%).

All 100% of clients are located in Russia, and an outdated application deals with forms issued by state authorities of Russia, so a country request will give 100% of the Russian Federation, and GeoIP will provide 80% of the Russian Federation and 20% of other (incorrect) answers.

+53
html internationalization locale
Jul 02 '09 at 14:19
source share
11 answers

Here is a simple JavaScript function that will return this information. Tested in Firefox, IE6 and IE7. I had to close and restart my browser between changes in the settings in the "Control Panel" / "Regional and Language Settings" / "Regional Settings / Configure". However, he took not only a comma and a period, but also unusual things, such as the letter "a".

 function whatDecimalSeparator() { var n = 1.1; n = n.toLocaleString().substring(1, 2); return n; } 

 function whatDecimalSeparator() { var n = 1.1; n = n.toLocaleString().substring(1, 2); return n; } console.log('You use "' + whatDecimalSeparator() + '" as Decimal seprator'); 

Does it help?

+89
Aug 20 '09 at 19:53
source share

Ask the user, do not guess. You have settings for your web application.

Edited to add:

I think that you can guess the default setting, which works fine, say, in 95% of cases. I meant that the user should still redefine any guesses made by the software. I was too upset when the software tries to be too smart and does not allow me to fix it.

+9
Jul 02 '09 at 14:59
source share
 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; } 
+8
Dec 12 '14 at 13:23
source share

I can guess the decimal separator from Accept-Language and the guess will be in 95% of cases, but sometimes it fails.

This is IMO's best course of action. To deal with errors, add a link to manually set it next to the display area.

+6
Jul 02 '09 at 15:13
source share

Why not

 0.1.toLocaleString().replace(/\d/g, '') 
+3
Oct 23 '15 at 21:13
source share

Well, I have something to show, rather a proof of concept than a finished product, but due to the lack of precise specifications, I leave it that way (or I retrain it). I am sending the message in a separate message because it will be a little long. I took the opportunity to try a little more jQuery ...

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); } } 

Example 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 problems with the first two, in Safari I have a strange error after calling init ():

 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 this to work with Opera: the applet loads correctly, since I see the trace of the init () call in the Java console, I have no errors when JavaScript calls Java functions (except when I add and call the method that receives the JSObject parameter , curious), but Java functions are not called (I added call tracing).
I believe Liveconnect works in Opera, but I don’t see how to do it yet. I will explore a little more. [Update] I deleted links to a nonexistent jar file (which does not stop other browsers), and I got a call trace, but it does not refresh the page.
Mmm if I do alert(applet.GetLocaleInformation()); I got the info, so this could be a jQuery problem.

+2
Jul 07 '09 at 10:20
source share

I think you should rely on JavaScript to give you locale settings.
But, obviously, JS does not have direct access to this information. I see the Dojo Toolkit relies on an external database to find locale information, although, for example, it may not account for changes to account settings.
Another workaround that I see is having a small silent Java applet that requests this information from the system, and JavaScript to get rid of Java.
I can give more information if you do not know how to do it (if you want to go through this confusing route, of course).

[EDIT] So I updated my knowledge of localization support in Java ...
Unlike what I was thinking initially, you won’t have directly decimal separators or thousands separators, just like for a line separator or a path separator: instead, Java offers an API for formatting the numbers or dates that you provide. One way or another, it makes sense: in Europe, you often put the currency symbol after the number, some countries (India?) Have a more complicated rule for separating numbers, etc.

Another thing: Java correctly finds the current language from the system, but does not accept information from there (perhaps for the above reasons). Instead, it uses its own set of rules. Therefore, if you have Spanish, where you replaced the decimal separator with an exclamation mark, Java will not use it (but maybe not your application, anyway ...).

So, I am writing an applet that provides JavaScript service (functions) that allows you to format numbers in the current locale. You can use it as such, using JavaScript to format numbers in the browser. Or you can simply upload it with some sample number and extract characters from it, using them locally or uploading them back to the server.

I am finishing and testing my applet and publishing it soon.

+1
Jul 02 '09 at 15:05
source share

Even if you knew in what locale this GUI Application is running, you still need to figure out how it gets the current locale and how it defines the decimal separator.

I don’t know how to do this on a Mac, but in Windows applications it’s supposed to interrogate user settings that are set using the control panel. It is possible that this covert application ignores these settings and instead uses its own internal setting.

Or maybe they take the current locale and output the rest, rather than talking.

Even then, in English, numbers are given in groups of 3 digits with a comma separating the groups. i.e:.

 5,197,359,078 

If the number was not an integer containing the phone number :

 519-735-9078 

Unless, of course, the number was an integer containing the account number :

 5197359078 

In this case, you will return to the hard-coded overridden logic.

Edit: The remote currency example, as the currency has its own formatting rules.

+1
Jul 04 '09 at 20:26
source share

"Is there a way to do this on the server (preferably so I can collect statistics) or on the client side?"

No, you can’t. This GUI looks for some user or machine settings. First, you probably don’t know what settings this user interface looks like. Secondly, using a web application, you probably cannot check these settings (clientside -> Javacsript).

0
Jul 02 '09 at 14:31
source share

Using other people's answers, I compiled the following decimal and thousands of separator utility functions:

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

Enjoy it!

0
Jun 01 '17 at 11:06 on
source share

Another possible solution: you can use something like GeoIP (an example in PHP) to determine the user's location and decide based on these information.

-2
Jul 02 '09 at 15:21
source share



All Articles