在Java中定制区域设置 [英] Customize a Locale in Java

查看:24
本文介绍了在Java中定制区域设置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Java中,Locale定义与人们希望看到事物的方式相关的内容(如货币格式、月份名称和一周开始的时间)。

分析月份名称(带有DateTimeFormatter)时,开始变得棘手。

如果使用Locale.USLocale.ENGLISH,则九月的缩写为Sep

如果您使用Locale.UK,那么在Java 11中,九月也有缩写Sep...但当您尝试Java 17时,它有Sept(因为Unicode CLDR端的变化I asked if this was correct)。

结果是,我的tests在尝试使用Java 17生成时开始失败。

我当前的代码使用Locale.UK而不是Locale.ENGLISH的原因是,在Java中Locale.ENGLISH实际上不仅是英语的,而且是非ISO美式的定义一周的方式(他们使用星期天作为一周的第一天)。我想用ISO的方式。

简单:

  • WeekFields.ISO=WeekFields.of(Locale.UK)=WeekFields[MONDAY,4]
  • WeekFields.of(Locale.ENGLISH)=WeekFields.of(Locale.US)=WeekFields[SUNDAY,1]

所以从Java 17开始,我还找不到能够正常工作的内置区域设置。

在我看来,我必须采用Locale.ENGLISH并将WeekFields更改为Locale.UK,或者采用Locale.UK将9月的短名称更改为我需要的月份。

我的问题是如何(在Java 17中)做到这一点?

或者是否有更好的方法来解决此问题?


更新1:

  • 我已经从Unicode的人那里得到了反馈,他们表示en_gb使用Sept而不是Sep的更改是一个错误,因为这是它在英国应该被缩写的方式。

因此,我似乎不仅需要一个接受";Sep";的解析器,还需要一个可以接受英语的";Sept";和";Sep";混合使用的解析器。

更新2:

  • 我调整了我的代码,在出现解析异常的情况下,它将尝试将假定为输入的内容(";Sep";)更改为当前选定的Locate喜欢的内容。这并不包括所有的情况,它涵盖了我的特定情况的足够的情况。 对于感兴趣的人:my commit

推荐答案

我找到了使用spi处理此问题的方法。

我在此将其记录为一种可能适用于其他人的可能性(不适用于我的上下文)。

作为实验,我创建了一个类:

package nl.basjes.parse.httpdlog.dissectors.locale;

import java.util.Locale;
import java.util.spi.CalendarDataProvider;

import static java.util.Calendar.MONDAY;

public class CalendarDataProviderISO8601 extends CalendarDataProvider {
    public static final Locale ENGLISH_ISO = new Locale("en", "", "ISO");

    @Override 
    public int getFirstDayOfWeek(Locale locale) {
        return MONDAY; 
    }

    @Override
    public int getMinimalDaysInFirstWeek(Locale locale) { 
        return 4; 
    }

    @Override
    public Locale[] getAvailableLocales() {
        return new Locale[]{ENGLISH_ISO}; 
    }
}

和带有

的文件./src/main/resources/META-INF/services/java.util.spi.CalendarDataProvider
nl.basjes.parse.httpdlog.dissectors.locale.CalendarDataProviderISO8601

因为这只是无区域英语和英语的变体,所以它将从英语和英语中提取所有内容,并将上面的类放在上面。

虽然此方法有效,但我无法使用它。

问题是,尽管http://openjdk.java.net/jeps/252描述了The default lookup order will be CLDR, COMPAT, SPI,,但当前的实际情况是,由于deprecating the Extension Mechanism,SPI已从this change中的此列表中删除。

因此,要使用此构造,类必须在启动时位于类路径中,并且命令行选项-Djava.locale.providers=CLDR,COMPAT,SPI必须传递给JVM。

鉴于我的库(https://github.com/nielsbasjes/logparser/)也用于以更动态的方式(序列化并传输到已经运行的JVM)将类发送到多台计算机的情况(如Apache Flink/Beam/Drill/Pig),此构造不能使用。

我目前不知道在Java中执行此类操作的dynamic方法。

这篇关于在Java中定制区域设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆