本文介紹了在Java中定制區(qū)域設(shè)置的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!
問題描述
在Java中,Locale
定義與人們希望看到事物的方式相關(guān)的內(nèi)容(如貨幣格式、月份名稱和一周開始的時間)。
分析月份名稱(帶有DateTimeFormatter
)時,開始變得棘手。
如果使用Locale.US
或Locale.ENGLISH
,則九月的縮寫為Sep
。
如果您使用Locale.UK
,那么在Java 11中,九月也有縮寫Sep
…但當(dāng)您嘗試Java 17時,它有Sept
(因?yàn)閁nicode CLDR端的變化I asked if this was correct)。
結(jié)果是,我的tests在嘗試使用Java 17生成時開始失敗。
我當(dāng)前的代碼使用Locale.UK
而不是Locale.ENGLISH
的原因是,在Java中Locale.ENGLISH
實(shí)際上不僅是英語的,而且是非ISO美式的定義一周的方式(他們使用星期天作為一周的第一天)。我想用ISO的方式。
簡單:
WeekFields.ISO
=WeekFields.of(Locale.UK)
=WeekFields[MONDAY,4]
WeekFields.of(Locale.ENGLISH)
=WeekFields.of(Locale.US)
=WeekFields[SUNDAY,1]
所以從Java 17開始,我還找不到能夠正常工作的內(nèi)置區(qū)域設(shè)置。
在我看來,我必須采用Locale.ENGLISH
并將WeekFields
更改為Locale.UK
,或者采用Locale.UK
將9月的短名稱更改為我需要的月份。
我的問題是如何(在Java 17中)做到這一點(diǎn)?
或者是否有更好的方法來解決此問題?
更新1:
我已經(jīng)從Unicode的人那里得到了反饋,他們表示en_gb使用Sept而不是Sep的更改是一個錯誤,因?yàn)檫@是它在英國應(yīng)該被縮寫的方式。
因此,我似乎不僅需要一個接受";Sep";的解析器,還需要一個可以接受英語的";Sept";和";Sep";混合使用的解析器。
更新2:
我調(diào)整了我的代碼,在出現(xiàn)解析異常的情況下,它將嘗試將假定為輸入的內(nèi)容(";Sep";)更改為當(dāng)前選定的Locate喜歡的內(nèi)容。這并不包括所有的情況,它涵蓋了我的特定情況的足夠的情況。
對于感興趣的人:my commit。
推薦答案
我找到了使用spi處理此問題的方法。
我在此將其記錄為一種可能適用于其他人的可能性(不適用于我的上下文)。
作為實(shí)驗(yàn),我創(chuàng)建了一個類:
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
因?yàn)檫@只是無區(qū)域英語和英語的變體,所以它將從英語和英語中提取所有內(nèi)容,并將上面的類放在上面。
雖然此方法有效,但我無法使用它。
問題是,盡管http://openjdk.java.net/jeps/252描述了The default lookup order will be CLDR, COMPAT, SPI,
,但當(dāng)前的實(shí)際情況是,由于deprecating the Extension Mechanism
,SPI已從this change中的此列表中刪除。
因此,要使用此構(gòu)造,類必須在啟動時位于類路徑中,并且命令行選項(xiàng)-Djava.locale.providers=CLDR,COMPAT,SPI
必須傳遞給JVM。
鑒于我的庫(https://github.com/nielsbasjes/logparser/)也用于以更動態(tài)的方式(序列化并傳輸?shù)揭呀?jīng)運(yùn)行的JVM)將類發(fā)送到多臺計(jì)算機(jī)的情況(如Apache Flink/Beam/Drill/Pig),此構(gòu)造不能使用。
我目前不知道在Java中執(zhí)行此類操作的dynamic
方法。
這篇關(guān)于在Java中定制區(qū)域設(shè)置的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,