gpt4 book ai didi

java Locale.Builder setExtension(Locale.UNICODE_LOCALE_EXTENSION

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:50:43 34 4
gpt4 key购买 nike

我一直在尝试让 Java 根据语言环境转换数字。偶遇this post这在很大程度上帮助了我预先理解这一点,我设计了自己的方法将数字转换为特定的语言环境(根据关于这个主题的其他混淆讨论)

所以假设我有:

Locale arabicLocale = new Locale.Builder().setLanguage("ar").setRegion("SA")
.setExtension(Locale.UNICODE_LOCALE_EXTENSION, "nu-arab").build();

Locale thaiLocale = new Locale.Builder().setLanguage("th").setRegion("TH")
.setExtension(Locale.UNICODE_LOCALE_EXTENSION, "nu-thai").build();

Locale hinduLocale = new Locale.Builder().setLanguage("hi").setRegion("IN")
.setExtension(Locale.UNICODE_LOCALE_EXTENSION, "nu-hindu").build();

DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(arabicLocale);
NumberFormat numberFormat = NumberFormat.getNumberInstance(arabicLocale);
println" Arabic ${numberFormat.format(123.22)}"

dfs = DecimalFormatSymbols.getInstance(thaiLocale);
numberFormat = NumberFormat.getNumberInstance(thaiLocale);
println" Thai ${numberFormat.format(123.22)}"

dfs = DecimalFormatSymbols.getInstance(hinduLocale);
numberFormat = NumberFormat.getNumberInstance(hinduLocale);
println" Hindu ${numberFormat.format(123.22)}"

这会产生以下输出

 Arabic ١٢٣٫٢٢
Thai ๑๒๓.๒๒
Hindu १२३.२२

这篇文章的目的是尝试确定我如何查找或让代码本身指向正确的 Locale.UNICODE_LOCALE_EXTENSION 因为 th 和印度教的东西只是我的猜测工作结束,我无法理解如何为希伯来语中文日语做同样的事情。虽然我认为中文和日文可能使用阿拉伯数字系统,但我在这一点上可能是错误的。

无论如何,任何关于我如何自动捕获这一点数据或标准的帮助/指示,就像在一个页面中一样,该页面具有我可以从中生成枚举的所有定义,这将有很大帮助

我正在深入研究 LocaleExtensions

static {
CALENDAR_JAPANESE = new LocaleExtensions("u-ca-japanese", Character.valueOf('u'), UnicodeLocaleExtension.CA_JAPANESE);
NUMBER_THAI = new LocaleExtensions("u-nu-thai", Character.valueOf('u'), UnicodeLocaleExtension.NU_THAI);
}

所以这现在更有意义了 nu-language = number ca-language = calendar

但是运行时:

Locale japLocale = new Locale.Builder().setLanguage("ja").setRegion("JP")
.setExtension(Locale.UNICODE_LOCALE_EXTENSION, "nu-japanese").build();

我得到英文数字。

根据原问题,链接 https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry

希伯来语

Type: language
Subtag: he
Description: Hebrew
Added: 2005-10-16
Suppress-Script: Hebr

但是在下面尝试时:

Locale hebrewLocale = new Locale.Builder().setLanguage("he").setRegion("IL")
.setExtension(Locale.UNICODE_LOCALE_EXTENSION, "nu-hebr").build();

我得到 123.22

要回答我自己的问题,您可以从此处构建一个枚举 http://www.oracle.com/technetwork/java/javase/java8locales-2095355.html

Greek (el) Greece (GR) (Grek)  el-GR
Hebrew (iw) Israel (IL) (Hebr) iw-IL

简而言之

对于希腊,取最后一个字段 el-GR unicodeEXtension=-u number=-nu 和最后一个小写 -hebr 为希腊提供 'el-GR-u-nu-grek' 或为希伯来文提供相同的 'iw-IL-u-n-hebr'

 Locale locale = new Locale.Builder().setLanguageTag('el-GR-u-nu-grek').build();

应该打印出希腊数字,但我看到它适用于某些国家/地区而不适用于其他国家/地区的英文数字。

最佳答案

回答我自己的问题,因为这是一个相当复杂的主题,目前还没有得到很好的解释。

简而言之,根据我的评论,您最好使用 icu4j 。因为这为国际数字/日期转换提供了更完整的解决方案。

困难在于制定所需的所有标准,因为它似乎确实支持所有区域设置语言等,只是知道如何正确使用它的情况。

我将提供一个片段 - 此代码需要清理,但为您的 Java 应用程序提供了数字和日期转换的解决方案:

import groovy.transform.CompileStatic

/**
*
* @author Vahid Hedayati
* Looks complex but will explain
*
* ar-SA u = unicode nu = number arab = arabic
*
* https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
* to get langauge code such as arab = subtag
*
* Rest explained here
* http://stackoverflow.com/questions/43456068/java-locale-builder-setextensionlocale-unicode-locale-extension
*
*
*/
@CompileStatic
enum LocaleCalendarExtensions {
SA('ar-SA-u-ca-arab'),
AM('hy-AM-u-ca-arevmda'),
CN('zh-TW-u-ca-hant'),
CZ('cs-CZ-u-ca-latn'),
DK('da-DK-u-ca-latn'),
NL('nl-NL-u-ca-latn'),
IE('ie-IE-u-ca-latn'),
FR('fr-FR-u-ca-latn'),
DE('de-DE-u-ca-latn'),
GR('el-GR-u-ca-grek'),
IL('iw-IL-u-ca-hebr'),
IN('hi-IN-u-ca-hindu'),
IT('it-IT-u-ca-latn'),
JP('ja-JP-u-ca-jpan'),
NO('nb-NO-u-ca-latn'),
IR(''), //fa-IR-u-ca-fars'),
PL('pl-PL-u-ca-latn'),
PT('pt-PT-u-ca-latn'),
RU('ru-RU-u-ca-cyrl'),
ES('es-ES-u-ca-latn'),
SE('sv-SE-u-ca-latn'),
TH('th-TH-u-ca-thai'),
TR('tr-TR-u-ca-latn'),
PK(''),//ur-PK-u-ca-arab'),
VN('vi-VN-u-ca-latn')

String value

LocaleCalendarExtensions(String val) {
this.value = val
}
public String getValue(){
return value
}
static LocaleCalendarExtensions byValue(String val) {
values().find { it.value == val }
}
public static EnumSet<LocaleCalendarExtensions> getArabicSupport() {
final EnumSet< LocaleCalendarExtensions > ret_val = EnumSet.noneOf( LocaleCalendarExtensions.class )
ret_val.add(SA)
return ret_val
}
public static EnumSet<LocaleCalendarExtensions> getJapanSupport() {
final EnumSet< LocaleCalendarExtensions > ret_val = EnumSet.noneOf( LocaleCalendarExtensions.class )
ret_val.add(JP)
return ret_val
}

public static EnumSet<LocaleCalendarExtensions> getChinaSupport() {
final EnumSet< LocaleCalendarExtensions > ret_val = EnumSet.noneOf( LocaleCalendarExtensions.class )
ret_val.add(CN)
return ret_val
}

public static EnumSet<LocaleCalendarExtensions> getFarsiSupport() {
final EnumSet< LocaleCalendarExtensions > ret_val = EnumSet.noneOf( LocaleCalendarExtensions.class )

ret_val.add(IR)
return ret_val
}
public static EnumSet<LocaleCalendarExtensions> getUrduSupport() {
final EnumSet< LocaleCalendarExtensions > ret_val = EnumSet.noneOf( LocaleCalendarExtensions.class )
ret_val.add(PK)
return ret_val
}
public static EnumSet<LocaleCalendarExtensions> getAsianSupport() {
final EnumSet< LocaleCalendarExtensions > ret_val = EnumSet.noneOf( LocaleCalendarExtensions.class )
ret_val.add(JP)
ret_val.add(CN)
return ret_val
}
public static EnumSet<LocaleCalendarExtensions> getHebrewSupport() {
final EnumSet< LocaleCalendarExtensions > ret_val = EnumSet.noneOf( LocaleCalendarExtensions.class )
ret_val.add(IL)
return ret_val
}
public static EnumSet<LocaleCalendarExtensions> getHinduSupport() {
final EnumSet< LocaleCalendarExtensions > ret_val = EnumSet.noneOf( LocaleCalendarExtensions.class )
ret_val.add(IN)
return ret_val
}
public static EnumSet<LocaleCalendarExtensions> getThaiSupport() {
final EnumSet< LocaleCalendarExtensions > ret_val = EnumSet.noneOf( LocaleCalendarExtensions.class )
ret_val.add(TH)
return ret_val
}
public static EnumSet<LocaleCalendarExtensions> getGreekSupport() {
final EnumSet< LocaleCalendarExtensions > ret_val = EnumSet.noneOf( LocaleCalendarExtensions.class )
ret_val.add(GR)
return ret_val
}
}

现在如何正确地将日期转换为国际语言环境:

 /**
*
* @param lang where lang code provider is ar en cn fr ur it is as per LocaleCalendarExtensions Enum main declarations
* @param date given date
* @param format definition in which case I have clause to deal with HH:mm and so on just read through below code
* @return
*/
public static String convertDate(String lang, java.util.Date date, String format) {
StringBuilder output=new StringBuilder()
if (lang != null && date) {
def found = LocaleICUCalendarExtensions?.find{it.toString()==lang}
if (found) {
def found1 = LocaleExtensions?.valueOf(lang)
com.ibm.icu.util.ULocale locale = new com.ibm.icu.util.ULocale(found1.value)
com.ibm.icu.util.Calendar calendar = com.ibm.icu.util.Calendar.getInstance(locale)
calendar.setTime(date)
com.ibm.icu.text.DateFormat df
if (format == 'HH:mm') {
df = com.ibm.icu.text.DateFormat.getPatternInstance( com.ibm.icu.text.DateFormat.HOUR_MINUTE, locale)
} else {
if (format=='dd MMM yyyy HH:mm:ss') {
df = com.ibm.icu.text.DateFormat.getDateInstance(DateFormat.FULL, locale)
} else if (format=='dd MMM') {
df = com.ibm.icu.text.DateFormat.getPatternInstance( com.ibm.icu.text.DateFormat.ABBR_MONTH_DAY, locale)
} else {
df = com.ibm.icu.text.DateFormat.getDateInstance(DateFormat.LONG, locale)
}
output << df.format(calendar)
}

}
}
return output.toString()
}

要将数字转换为另一个国家/地区的编号系统:

/**
* Converts number to given locale
* @param lang
* @param number
* @return
*/
public static String convertNumber(String lang, number) {
String output=''
if (lang != null) {
boolean arabic = (LocaleCalendarExtensions.arabicSupport.find { it.toString() == lang } ? true : false)
boolean china = (LocaleCalendarExtensions.chinaSupport.find { it.toString() == lang } ? true : false)
boolean japan = (LocaleCalendarExtensions.japanSupport.find { it.toString() == lang } ? true : false)
boolean farsi = (LocaleCalendarExtensions.farsiSupport.find { it.toString() == lang } ? true : false)
boolean urdu = (LocaleCalendarExtensions.urduSupport.find { it.toString() == lang } ? true : false)
boolean hebrew = (LocaleCalendarExtensions.hebrewSupport.find { it.toString() == lang } ? true : false)
boolean greek = (LocaleCalendarExtensions.greekSupport.find { it.toString() == lang } ? true : false)
boolean hindu = (LocaleCalendarExtensions.hinduSupport.find { it.toString() == lang } ? true : false)
boolean thai = (LocaleCalendarExtensions.thaiSupport.find { it.toString() == lang } ? true : false)
if (arabic || hindu | thai || farsi||urdu) {
def found = LocaleExtensions?.valueOf(lang)
if (found) {
Locale locale = new Locale.Builder().setLanguageTag(found.value).build();
DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(locale);
NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);
def numbers
if (number.toString().indexOf('.')>-1) {
numbers=number as Double
} else {
numbers=number as Long
}
output = (numberFormat?.format(numbers)) ?:''
}
}
if (japan|china||hebrew||greek) {
// to extend look up types here
//http://www.atetric.com/atetric/javadoc/com.ibm.icu/icu4j/49.1/src-html/com/ibm/icu/util/ULocale.html
//http://icu-project.org/~yoshito/jacoco_57.1/com.ibm.icu.util/ULocale.java.html
com.ibm.icu.util.ULocale locale

if (japan) {
locale= new com.ibm.icu.util.ULocale("ja_JP_JP")//ja_JP_JP //
}
if (china) {
locale= new com.ibm.icu.util.ULocale("zh_Hans")//zh_CN_TRADITIONAL@collation=pinyin;
}
if (hebrew) {
locale= new com.ibm.icu.util.ULocale("he_IL")

}
if (greek) {
locale= new com.ibm.icu.util.ULocale("el_GR")
}
com.ibm.icu.text.NumberFormat nf = com.ibm.icu.text.NumberFormat.getInstance(locale)
def numbers
if (number.toString().indexOf('.')>-1) {
numbers=number as Double
} else {
numbers=number as Long
}
output = nf.format(numbers)
}
}
return output ?: number.toString()
}

现在,如果您使用的是 grails,您可以创建一个 taglib 并覆盖 formatDate 和 formatNumber 定义以使用上面的代码:

 /**
* override default date formatter if translation translate
*/

def formatDate={attrs->
String foundRecord
if (attrs.locale) {
String lang = attrs.locale.country
foundRecord = NumberHelper.convertDate(lang, attrs.date, attrs.format)
}
if (!foundRecord || foundRecord=='null') {
out << g.formatDate(attrs)
} else {
out << foundRecord
}
}


/**
* Override default formatNumber and translate number if possible otherwsie run default
*/
def formatNumber={attrs->
def foundRecord
if (attrs.locale && attrs.number) {
String lang = attrs.locale.country
foundRecord = NumberHelper.convertNumber(lang, attrs.number)
}
if (!foundRecord) {
out << g.formatNumber(attrs)
} else {
out << "${foundRecord}"
}
}

上面的 ICU4J 枚举:

import groovy.transform.CompileStatic


@CompileStatic
enum LocaleICUCalendarExtensions {
SA('ar_SA@calendar=islamic'),
AM('hy_AM@calendar=armenian'),
CN('zh_Hans@calendar=chinese'),
CZ('cs_CZ@calendar=latin'),
DK('da_DK@calendar=latin'),
NL('nl_NL@calendar=latin'),
IE('ie_IE@calendar=latin'),
FR('fr_FR@calendar=latin'),
DE('de_DE@calendar=latin'),
GR('el_GR@calendar=greek'),
IL('iw_IL@calendar=hebrew'),
IN('hi_IN@calendar=hindu'),
IT('it_IT@calendar=Latin'),
JP('ja_JP_TRADITIONAL@calendar=japanese'),
NO('nb_NO@calendar=latin'),
IR('fa_IR@calendar=persian'),
PL('pl_PL@calendar=latin'),
PT('pt_PT@calendar=latin'),
RU('ru_RU@calendar=cyrillic'),
ES('es_ES@calendar=latin'),
SE('sv_SE@calendar=latin'),
TH('th_TH_TRADITIONAL@calendar=buddhist'),
TR('tr_TR@calendar=latin'),
PK('ur_PK@calendar=pakistan'),
VN('vi_VN@calendar=latin')

String value

LocaleICUCalendarExtensions(String val) {
this.value = val
}
public String getValue(){
return value
}
static LocaleICUCalendarExtensions byValue(String val) {
values().find { it.value == val }
}
public static EnumSet<LocaleICUCalendarExtensions> getArabicSupport() {
final EnumSet< LocaleICUCalendarExtensions > ret_val = EnumSet.noneOf( LocaleICUCalendarExtensions.class )
ret_val.add(SA)
return ret_val
}
public static EnumSet<LocaleICUCalendarExtensions> getJapanSupport() {
final EnumSet< LocaleICUCalendarExtensions > ret_val = EnumSet.noneOf( LocaleICUCalendarExtensions.class )
ret_val.add(JP)
return ret_val
}

public static EnumSet<LocaleICUCalendarExtensions> getChinaSupport() {
final EnumSet< LocaleICUCalendarExtensions > ret_val = EnumSet.noneOf( LocaleICUCalendarExtensions.class )
ret_val.add(CN)
return ret_val
}

public static EnumSet<LocaleICUCalendarExtensions> getFarsiSupport() {
final EnumSet< LocaleICUCalendarExtensions > ret_val = EnumSet.noneOf( LocaleICUCalendarExtensions.class )

ret_val.add(IR)
return ret_val
}
public static EnumSet<LocaleICUCalendarExtensions> getUrduSupport() {
final EnumSet< LocaleICUCalendarExtensions > ret_val = EnumSet.noneOf( LocaleICUCalendarExtensions.class )
ret_val.add(PK)
return ret_val
}

public static EnumSet<LocaleICUCalendarExtensions> getHebrewSupport() {
final EnumSet< LocaleICUCalendarExtensions > ret_val = EnumSet.noneOf( LocaleICUCalendarExtensions.class )
ret_val.add(IL)
return ret_val
}
public static EnumSet<LocaleICUCalendarExtensions> getHinduSupport() {
final EnumSet< LocaleICUCalendarExtensions > ret_val = EnumSet.noneOf( LocaleICUCalendarExtensions.class )
ret_val.add(IN)
return ret_val
}
public static EnumSet<LocaleICUCalendarExtensions> getThaiSupport() {
final EnumSet< LocaleICUCalendarExtensions > ret_val = EnumSet.noneOf( LocaleICUCalendarExtensions.class )
ret_val.add(TH)
return ret_val
}
public static EnumSet<LocaleICUCalendarExtensions> getGreekSupport() {
final EnumSet< LocaleICUCalendarExtensions > ret_val = EnumSet.noneOf( LocaleICUCalendarExtensions.class )
ret_val.add(GR)
return ret_val
}
}

LocaleExtensions 枚举有点像 LocaleCalendar 只是有 nu 而不是 ca

import groovy.transform.CompileStatic

/**
* Looks complex but will explain
*
* ar-SA u = unicode nu = number arab = arabic
*
* https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
* to get langauge code such as arab = subtag
*
* Rest explained here
* http://stackoverflow.com/questions/43456068/java-locale-builder-setextensionlocale-unicode-locale-extension
*
*
*/
@CompileStatic
enum LocaleExtensions {
SA('ar-SA-u-nu-arab'),
AM('hy-AM-u-nu-arevmda'),
CN('zh-TW-u-nu-arab'), //'zh-TW-u-nu-hant'
CZ('cs-CZ-u-nu-latn'),
DK('da-DK-u-nu-latn'),
NL('nl-NL-u-nu-latn'),
IE('ie-IE-u-nu-latn'),
FR('fr-FR-u-nu-latn'),
DE('de-DE-u-nu-latn'),
GR('el-GR-u-nu-grek'),
IL('iw-IL-u-nu-hebr'),
IN('hi-IN-u-nu-hindu'),
IT('it-IT-u-nu-latn'),
JP('ja-JP-u-nu-arab'),
NO('nb-NO-u-nu-latn'),
IR('fa-IR-u-nu-arab'),
PL('pl-PL-u-nu-latn'),
PT('pt-PT-u-nu-latn'),
RU('ru-RU-u-nu-cyrl'),
ES('es-ES-u-nu-latn'),
SE('sv-SE-u-nu-latn'),
TH('th-TH-u-nu-thai'),
TR('tr-TR-u-nu-latn'),
PK('ur-PK-u-nu-arab'),
VN('vi-VN-u-nu-latn')

String value

LocaleExtensions(String val) {
this.value = val
}
public String getValue(){
return value
}
static LocaleExtensions byValue(String val) {
values().find { it.value == val }
}
public static EnumSet<LocaleExtensions> getArabicSupport() {
final EnumSet< LocaleExtensions > ret_val = EnumSet.noneOf( LocaleExtensions.class )
ret_val.add(SA)
//TODO
ret_val.add(JP)
ret_val.add(CN)
return ret_val
}
public static EnumSet<LocaleExtensions> getFarsiSupport() {
final EnumSet< LocaleExtensions > ret_val = EnumSet.noneOf( LocaleExtensions.class )
ret_val.add(PK)
ret_val.add(IR)
return ret_val
}

public static EnumSet<LocaleExtensions> getAsianSupport() {
final EnumSet< LocaleExtensions > ret_val = EnumSet.noneOf( LocaleExtensions.class )
ret_val.add(JP)
ret_val.add(CN)
return ret_val
}
public static EnumSet<LocaleExtensions> getHebrewSupport() {
final EnumSet< LocaleExtensions > ret_val = EnumSet.noneOf( LocaleExtensions.class )
ret_val.add(IL)
return ret_val
}
public static EnumSet<LocaleExtensions> getHinduSupport() {
final EnumSet< LocaleExtensions > ret_val = EnumSet.noneOf( LocaleExtensions.class )
ret_val.add(IN)
return ret_val
}
public static EnumSet<LocaleExtensions> getThaiSupport() {
final EnumSet< LocaleExtensions > ret_val = EnumSet.noneOf( LocaleExtensions.class )
ret_val.add(TH)
return ret_val
}
public static EnumSet<LocaleExtensions> getGreekSupport() {
final EnumSet< LocaleExtensions > ret_val = EnumSet.noneOf( LocaleExtensions.class )
ret_val.add(GR)
return ret_val
}
}

这显然涵盖了一系列语言环境,用 Bernard Manning 的 bootifuly 的话来说它对我来说工作正常

日期已分为默认支持的 java 与 icu4j,然后当理解得更好时,所有转移到 icu4j 我认为编号系统仍在使用一半和一半,可能也可以切换到 icu4j。

无论如何,答案是一列脱轨的火车,从它开始的地方到现在,它正在将数字字符转换为数字字符,例如从拉丁语到阿拉伯语,这很难理解工作,因为在阿拉伯语中给出了 2016 年的拉丁年在沙特阿拉伯,等效且正确的年份应该是 1354 年,或者在泰国,我认为是 2056 年

关于java Locale.Builder setExtension(Locale.UNICODE_LOCALE_EXTENSION,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43456068/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com