简体   繁体   English

Android Java.Lang Locale Number Format I/O 不对称问题

[英]Android Java.Lang Locale Number Format I/O Asymmetry Problem

Historically the Android phones sold in South Africa provided English.US and English.UK locale support, but recently English.ZA (South Africa) has made an appearance, on Android 9.0 Samsung Galaxy A10, for example.从历史上看,在南非销售的 Android 手机提供 English.US 和 English.UK 语言环境支持,但最近 English.ZA(南非)出现在 Android 9.0 三星 Galaxy A10 上,例如。

This particular Locale is showing asymmetric treatment of number formats, using the Locale.DE (German/Dutch) convention when converting Floats and Doubles into character strings[*1], but raising Java.Lang.NumberFormatException when reading back the self-same generated strings.这个特殊的 Locale 显示了对数字格式的不对称处理,在将 Floats 和 Doubles 转换为字符串时使用 Locale.DE(德语/荷兰语)约定[*1],但在读回相同生成的字符串时引发 Java.Lang.NumberFormatException字符串。 For instance:例如:

// on output
Float fltNum = 1.23456F;
System.out.println(String.format(Locale.getDefault(),"%f",fltNum)); // prints '1,23456'
// on Input
String fltStr = "1,23456";
Float fltVal;
fltVal = Float(fltStr); // generates NumberFormatException
fltVal = Float.parseFloat(fltStr); // also generates NumberFormatException
// Giving the compiler Float hints fltStr = "1,23456F" does not help
// Only fltStr = '1.23456' converts into a Float.

The temptation would be to swap decimal separators on reads, but that is the task of Float.parseFloat(), a not of the programer, for doing so shall again break other Locale.DE-likes, such as Locale.ID (Indonesia) which my App supports.诱惑是在读取时交换小数点分隔符,但这是 Float.parseFloat() 的任务,不是程序员的任务,因为这样做将再次破坏其他类似 Locale.DE 的方法,例如 Locale.ID(印度尼西亚)我的应用程序支持。

My additional question directed more at Locale arbitrators is: Does English.ZA not imply English conformant as would say German.NA (Namibia) be German conformant?我更多针对语言环境仲裁员的附加问题是:English.ZA 是否意味着符合英语,就像 German.NA(纳米比亚)符合德语一样? One would think the natural designation for this particular number conversion would be Dutch.ZA (colloquially 'Afrikaans'), for Dutch conformance, but Android designates it as English.ZA?人们会认为这种特定数字转换的自然名称是 Dutch.ZA(通俗地说是“南非荷兰语”),以符合荷兰语,但 Android 将其指定为 English.ZA?

NB (*1) This Android English.ZA conforms only partially as it does not produce either the German point group separator or the local clerical (pen-and-paper) space character group separator. NB (*1) 此 Android English.ZA 仅部分符合,因为它既不生成德语点组分隔符,也不生成本地文书(笔和纸)空格字符组分隔符。

Apologies for using 'Answer' to respond to diogenesgg's comment suggestion:对使用“答案”回应 diogenesgg 的评论建议表示歉意:

"Hi, please take a look at this answer stackoverflow.com/questions/5233012/…. TL/DR."

In it I found a few gems - (1)在里面我发现了一些宝石 - (1)

NumberFormat f = NumberFormat.getInstance(Locale.getDefault());
if (f instanceof DecimalFormat) {
    ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
}

But this is neutral and not value-specific so I added after the above,但这是中性的,不是特定于价值的,所以我在上面添加了,

(2) Given: (2) 给定:

String axisValue("some-float-value-rendered as string");
NumberFormat nf = new DecimalFormat(axisValue);

Which I incorporate sequentially:我按顺序合并:

NumberFormat nf = new DecimalFormat(axisValue);
Number n;
if(nf instanceof DecimalFormat){
    try{
        n = nf.parse (axisValue);
        axisComponent = (Double) n;
    } catch (java.text.ParseException jtpe) {
    jtpe.printStackTrace();
    }
}

Notice the need to cast the Number n to Double.请注意需要将 Number n 转换为 Double。

This worked mostly under the problematic Locale English.ZA, until the value 0,00000 showed up.这主要在有问题的 Locale English.ZA 下工作,直到值 0,00000 出现。

For the string value "0,00000", NumberFormat decides Number n is a Long, and the system throws a (Long to Double) CastException.对于字符串值“0,00000”,NumberFormat 决定 Number n 为 Long,系统抛出(Long to Double)CastException。

I tried to trick NumberFormat in all ways I can to view 0 as a Float or Double to no avail, so 0 is a border problem that Number (NumberFormat.DecimalFormat) does not tolerate.我试图以各种方式欺骗 NumberFormat 我可以将 0 视为 Float 或 Double 无济于事,因此 0 是 Number (NumberFormat.DecimalFormat) 不能容忍的边界问题。

But this NumberFormat workaround does not resolve the assymmetry problem of Android 9 Locale.English(ZA).DecimalFormat emitting Locale.DE (comma decimal separator) but parsing only System.Primitives (decimal dot separator).但是这个 NumberFormat 解决方法并没有解决 Android 9 Locale.English(ZA).DecimalFormat 发出 Locale.DE(逗号小数分隔符)但只解析 System.Primitives(十进制点分隔符)的不对称问题。

Incidentally, getting past the DecimalFormat problem exposed a myriad of other problems under this new-fangled English.ZA, of my App assuming system primitives working equally well with native resources.顺便说一句,在这个新奇的 English.ZA 下,解决了 DecimalFormat 问题暴露了无数其他问题,我的应用程序假设系统原语与本机资源同样有效。 Well semantics so used require string comparison to work between primitive and native!如此使用的语义需要字符串比较才能在原始和本机之间工作!

For example system file Primitive path names rendered in Native generating 'file not found', or even more problematic, using primitive string keys semantically only to being rendered meaningless on Native lookup.例如,在 Native 中呈现的系统文件原始路径名会生成“找不到文件”,或者甚至更成问题,在语义上使用原始字符串键只会在 Native 查找中呈现无意义。

I'm not sure which is the lesser evil, assymmetric locale English.ZA or my use of Primitives in semantics to thrust upon Natives.我不确定哪个是较小的邪恶,不对称的语言环境 English.ZA 或我在语义中使用 Primitives 来强加给 Natives。 A futile exercise!徒劳的练习!

Right now I'm embarking on separating system primitives, including their semantic variants from ANY Native language resource strings ...现在我正在着手分离系统原语,包括它们的语义变体与任何本地语言资源字符串......

My lifetime of programming under system primitives needs an overall makeover.我在系统原语下的编程生涯需要全面改造。

Maybe I can keep an Assets repository for the primitives (resource or semantic) and have Natives look that up for system resources or for semantic Meaning.也许我可以为原语(资源或语义)保留一个资产存储库,并让 Natives 查找系统资源或语义含义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM