首页 > 解决方案 > Android Java.Lang 语言环境数字格式 I/O 不对称问题

问题描述

过去,在南非销售的 Android 手机提供 English.US 和 English.UK 语言环境支持,但最近 English.ZA(南非)出现在 Android 9.0 Samsung Galaxy A10 上。

这个特殊的 Locale 显示了数字格式的不对称处理,在将 Floats 和 Doubles 转换为字符串 [*1] 时使用 Locale.DE(德语/荷兰语)约定,但在读回生成的自身相同时引发 Java.Lang.NumberFormatException字符串。例如:

// 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.

诱惑是在读取时交换小数分隔符,但这是 Float.parseFloat() 的任务,不是程序员的任务,因为这样做会再次破坏其他 Locale.DE-likes,例如 Locale.ID (Indonesia)我的应用程序支持。

我更多地针对区域设置仲裁员的另一个问题是:English.ZA 是否暗示符合英语,就像说 German.NA(纳米比亚)符合德国一样?有人会认为这种特定数字转换的自然名称是 Dutch.ZA(俗称“南非荷兰语”),以符合荷兰语,但 Android 将其指定为 English.ZA?

注意 (*1) 此 Android English.ZA 仅部分符合,因为它不生成德语点组分隔符或本地文书(纸笔)空格字符组分隔符。

标签: androidexceptionnumberslocalejava.lang

解决方案


很抱歉使用“答案”来回应 diogenesgg 的评论建议:

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

在其中我发现了一些宝石 - (1)

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

但这是中性的,不是特定于价值的,所以我在上面添加了,

(2) 鉴于:

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

我按顺序合并:

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

注意需要将数字 n 转换为 Double。

这主要在有问题的 Locale English.ZA 下工作,直到出现值 0,00000。

对于字符串值“0,00000”,NumberFormat 判断 Number n 为 Long,系统抛出(Long to Double)CastException。

我试图以各种方式欺骗 NumberFormat 将 0 视为 Float 或 Double 无济于事,因此 0 是 Number (NumberFormat.DecimalFormat) 不能容忍的边界问题。

但是这个 NumberFormat 解决方法不能解决 Android 9 Locale.English(ZA).DecimalFormat 发出 Locale.DE(逗号小数分隔符)但仅解析 System.Primitives(小数点分隔符)的不对称问题。

顺便说一句,克服 DecimalFormat 问题在这个新奇的 English.ZA 下暴露了无数其他问题,我的应用程序假设系统原语与本地资源同样好用。如此使用的良好语义需要字符串比较才能在原始和本机之间工作!

例如,系统文件原始路径名在 Native 中呈现,生成“找不到文件”,或者更成问题的是,在语义上使用原始字符串键仅在 Native 查找时呈现无意义。

我不确定哪个是较小的邪恶,不对称的语言环境 English.ZA 或我在语义中使用 Primitives 来强加 Natives。徒劳的练习!

现在我正在着手分离系统原语,包括它们与任何本机语言资源字符串的语义变体......

我在系统原语下的编程生涯需要全面改造。

也许我可以为原语(资源或语义)保留一个资产存储库,并让 Natives 查找系统资源或语义含义。


推荐阅读