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






