本文介紹了在Java中定制區域設置的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
在Java中,Locale
定義與人們希望看到事物的方式相關的內容(如貨幣格式、月份名稱和一周開始的時間)。
分析月份名稱(帶有DateTimeFormatter
)時,開始變得棘手。
如果使用Locale.US
或Locale.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中定制區域設置的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,