Html 使用浏览器,我如何知道操作系统使用哪个小数点分隔符?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1074660/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
With a browser, how do I know which decimal separator does the operating system use?
提问by Quassnoi
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 is not under my control.
我需要正确显示一些十进制数据,以便可以将其复制并粘贴到某个GUI
不受我控制的应用程序中。
The GUI application is locale sensitive and it accepts only the correct decimal separator which is set in the system.
GUI 应用程序对区域设置敏感,它只接受系统中设置的正确小数点分隔符。
I can guess the decimal separator from Accept-Language
and the guess will be correct in 95% cases, but sometimes it fails.
我可以猜测小数点分隔符,Accept-Language
并且猜测在 95% 的情况下是正确的,但有时它会失败。
Is there any way to do it on server side (preferably, so that I can collect statistics), or on client side?
有什么办法可以在服务器端(最好是这样我可以收集统计信息)或客户端?
Update:
更新:
The whole point of the task is doing it automatically.
任务的重点是自动完成。
In fact, this webapp is a kind of online interface to a legacy GUI which helps to fill the forms correctly.
事实上,这个 web 应用程序是一种传统 GUI 的在线界面,有助于正确填写表单。
The kind of users that use it mostly have no idea on what a decimal separator is.
使用它的用户大多不知道小数点分隔符是什么。
The Accept-Language
solution is implemented and works, but I'd like to improve it.
该Accept-Language
解决方案已实施并有效,但我想对其进行改进。
Update2:
更新2:
I need to retrive a very specific setting: decimal separator set in Control Panel / Regional and Language Options / Regional Options / Customize
.
我需要检索一个非常具体的设置:在Control Panel / Regional and Language Options / Regional Options / Customize
.
I deal with four kinds of operating systems:
我处理四种操作系统:
- Russian Windows with a comma as a DS (80%).
- English Windows with a period as a DS (15%).
- Russian Windows with a period as a DS to make poorly written English applications work (4%).
- English Windows with a comma as a DS to make poorly written Russian applications work (1%).
- 用逗号作为 DS 的俄语 Windows (80%)。
- 带有句点作为 DS (15%) 的英文 Windows。
- 俄语 Windows 用句号作为 DS 使写得不好的英语应用程序工作 (4%)。
- 用逗号作为 DS 的英文 Windows 使写得不好的俄语应用程序工作 (1%)。
All 100% of clients are in Russia and the legacy application deals with Russian goverment-issued forms, so asking for a country will yield 100% of Russian Federation, and GeoIP will yield 80% of Russian Federation and 20% of other (incorrect) answers.
所有 100% 的客户都在俄罗斯,并且遗留应用程序处理俄罗斯政府颁发的表格,因此要求一个国家将产生 100% 的俄罗斯联邦,GeoIP 将产生 80% 的俄罗斯联邦和 20% 的其他(不正确)答案。
回答by Chris Nielsen
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 in between every change to the setting under Control Panel / Regional and Language Options / Regional Options / Customize. However, it picked up not only the comma and period, but also oddball custom things, like the letter "a".
这是一个简单的 JavaScript 函数,它将返回此信息。在 Firefox、IE6 和 IE7 中测试。在每次更改控制面板/区域和语言选项/区域选项/自定义下的设置之间,我不得不关闭并重新启动浏览器。但是,它不仅提取了逗号和句点,还提取了奇怪的自定义内容,例如字母“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 this help?
这有帮助吗?
回答by JBE
Retrieving separators for the current or a given locale is possible using Intl.NumberFormat#formatToParts
.
可以使用 检索当前或给定语言环境的分隔符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
它仅适用于支持 Intl API 的浏览器。否则它需要一个Intl polyfill
Examples:
例子:
> getDecimalSeparator()
"."
> getDecimalSeparator('fr-FR')
","
Bonus:
奖金:
We could extend it to retrieve either the decimalor groupseparator 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')
" "
回答by laalto
Ask the user, do not guess. Have a setting for it in your web application.
询问用户,不要猜测。在您的 Web 应用程序中对其进行设置。
Edited to add:
编辑添加:
I think it is ok to guess the defaultsetting that works ok, say, 95% of the time. What I meant was that the user should still be able to override whatever guesses the software made. I've been frustrated too many times already when a software tries to be too smart and does not allow to be corrected.
我认为可以猜测默认设置可以正常工作,例如 95% 的时间。我的意思是用户仍然应该能够覆盖软件所做的任何猜测。当一个软件试图变得太聪明并且不允许被纠正时,我已经沮丧了太多次。
回答by Dr.Oblak
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;
}
回答by user3023011
Why not
为什么不
0.1.toLocaleString().replace(/\d/g, '')
回答by Michael Borgwardt
I can guess the decimal separator from Accept-Language and the guess will be correct in 95% cases, but sometimes it fails.
我可以从 Accept-Language 中猜测小数点分隔符,并且猜测在 95% 的情况下是正确的,但有时它会失败。
This is IMO the best course of action. In order to handle the failures, add a link to set it manually next to the display area.
这是 IMO 的最佳行动方案。为了处理故障,添加一个链接以在显示区域旁边手动设置它。
回答by Juangui Jordán
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!
享受!
回答by Ian Boyd
Even if you knew what locale this "GUI Application" is running under, you still have to figure out how itis getting the current locale, and how itis determining the decimal separator.
即使您知道这个“GUI 应用程序”在什么语言环境下运行,您仍然需要弄清楚它是如何获取当前语言环境的,以及它如何确定小数点分隔符。
i don't know how it is done on a Mac, but on Windows applications are supposed to interrogte the user's preferences set via the Control Panel. It's quite possible this mystery applicaiton is ignoring those settings, and using their own internal setup instead.
我不知道它是如何在 Mac 上完成的,但在 Windows 上,应用程序应该询问通过控制面板设置的用户首选项。这个神秘的应用程序很可能会忽略这些设置,而是使用他们自己的内部设置。
Or perhaps they're taking the current locale, and inferring the rest, rather than being told.
或者他们可能正在使用当前的语言环境,并推断出其余的语言环境,而不是被告知。
Even then, in english, numbersare given in groups of 3 digits, with a comma separating the groups. i.e.:
即便如此,在英语中,数字还是以 3 位数为一组给出,并用逗号分隔各组。IE:
5,197,359,078
Unless the number was an integer that contains a phone number:
除非号码是包含电话号码的整数:
519-735-9078
Unless of course the number was an integer that contains an account number:
当然,除非数字是包含帐号的整数:
5197359078
In which case, you're back to hard-coded overridden logic.
在这种情况下,您将回到硬编码的覆盖逻辑。
Edit: Removed currency example, since currency has its own formatting rules.
编辑:删除了货币示例,因为货币有自己的格式规则。
回答by PhiLho
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...
好吧,我有一些东西要展示,更多的是概念证明而不是成品,但由于缺乏精确的规格,我就这样(否则我会过度设计它)。我在单独的消息中发布,因为它会有点长。我借此机会尝试了更多 jQuery ...
The Java code: GetLocaleInfo.java
Java 代码: 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
使用上述小程序的 HTML 页面示例: 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:
在 Firefox 3.0、IE 6、Safari 3.1 和 Opera 9.50、Windows XP Pro SP3 上测试。它对前两个没有问题,在 Safari 上我在 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##代码##0(Unknown Source)
at sun.plugin.liveconnect.SecureInvocation.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.
我无法使用 Opera:小程序加载正确,因为我可以在 Java 控制台中看到 init() 调用的踪迹,当 JavaScript 调用 Java 函数时我没有错误(除非我添加并调用一个方法奇怪的是,获得了一个 JSObject 参数),但是没有调用 Java 函数(我添加了调用的跟踪)。
我相信 Liveconnect 可以在 Opera 中使用,但我还不知道如何使用。我会再研究一点。
[更新] 我删除了对不存在的 jar 文件的引用(它不会停止其他浏览器)并且我得到了调用的跟踪,但它没有更新页面。
嗯,如果我alert(applet.GetLocaleInformation());
得到了信息,那么它可能是一个 jQuery 问题。
回答by PhiLho
I think you have to rely on JavaScript to give you the locale settings.
But apparently JS doesn't have direct access to this information.
I see Dojo Toolkitrelies on an external database to find the locale information, although it might not take in account setting changes, for example.
Another workaround I see is to have a small silent Java applet that query this information from the system, and JavaScript to get it out of Java.
I can give more information if you don't know how to do it (if you want to go this convoluted route, of course).
我认为您必须依靠 JavaScript 来为您提供语言环境设置。
但显然 JS 无法直接访问这些信息。
我看到Dojo Toolkit依赖于外部数据库来查找区域设置信息,尽管它可能不考虑帐户设置更改,例如。
我看到的另一个解决方法是使用一个小的静默 Java 小程序从系统中查询此信息,并使用 JavaScript 将其从 Java 中获取。
如果您不知道该怎么做,我可以提供更多信息(当然,如果您想走这条复杂的路线)。
[EDIT]
So I updated my knowledge of localization support in Java...
Unlike what I thought originally, you won't have directly the decimal separator or thousand separator characters directly, like you would do with line separator or path separator: instead Java offers APIs to format the numbers or dates you provide.
Somehow, it makes sense: in Europe you often put the currency symbol after the number, some countries (India?) have a more complex rule to separate digits, etc.
[编辑] 所以我更新了我对 Java 本地化支持的了解......
与我最初的想法不同,您不会直接使用小数分隔符或千位分隔符,就像使用行分隔符或路径分隔符一样:而是 Java提供 API 来格式化您提供的数字或日期。
不知何故,这是有道理的:在欧洲,您经常将货币符号放在数字之后,有些国家(印度?)有更复杂的规则来分隔数字等。
Another thing: Java correctly finds the current locale from the system, but doesn't take information from there (perhaps for above reasons). Instead it uses its own set of rules. So if you have a Spanish locale where you replaced decimal separator with an exclamation sign, Java won't use it (but perhaps neither your application, anyway...).
另一件事:Java 正确地从系统中找到了当前的语言环境,但不会从那里获取信息(可能出于上述原因)。相反,它使用自己的一套规则。因此,如果您有一个用感叹号替换小数点分隔符的西班牙语语言环境,Java 将不会使用它(但也许您的应用程序也不会使用它......)。
So I am writing an applet exposing a service (functions) to JavaScript, allowing to format numbers to the current locale. You can use it as such, using JavaScript to format numbers on the browser. Or you can just feed it with some sample number and extract the symbols from there, using them locally or feeding them back to the server.
所以我正在编写一个向 JavaScript 公开服务(函数)的小程序,允许将数字格式化为当前语言环境。您可以使用它,使用 JavaScript 在浏览器上格式化数字。或者您可以只提供一些样本编号并从那里提取符号,在本地使用它们或将它们反馈给服务器。
I finish and test my applet and post it there soon.
我完成并测试了我的小程序,并很快将其发布到那里。