回答我自己的问题,因为这是一个复杂的话题,没有很好地解释。
简而言之,根据我的评论,你可能更好使用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")//[email protected]=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,您可以创建一个标签库,并覆盖formatDate和formatNumber defintions与上面的代码工作:
/**
* 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('[email protected]=islamic'),
AM('[email protected]=armenian'),
CN('[email protected]=chinese'),
CZ('[email protected]=latin'),
DK('[email protected]=latin'),
NL('[email protected]=latin'),
IE('[email protected]=latin'),
FR('[email protected]=latin'),
DE('[email protected]=latin'),
GR('[email protected]=greek'),
IL('[email protected]=hebrew'),
IN('[email protected]=hindu'),
IT('[email protected]=Latin'),
JP('[email protected]=japanese'),
NO('[email protected]=latin'),
IR('[email protected]=persian'),
PL('[email protected]=latin'),
PT('[email protected]=latin'),
RU('[email protected]=cyrillic'),
ES('[email protected]=latin'),
SE('[email protected]=latin'),
TH('[email protected]=buddhist'),
TR('[email protected]=latin'),
PK('[email protected]=pakistan'),
VN('[email protected]=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
}
}
这显然涵盖了一系列的语言环境,它是在伯纳的话正常工作对我来说rd Manning's bootifuly
日期已被分成java支持默认vs icu4j然后当更好地理解所有移动到icu4j我认为编号系统仍然使用一半和一半,可能也可以切换到icu4j了。
无论如何,这是从我开始从哪里开始,这是从拉丁文转换数字字符到阿拉伯文讨厌的讨厌的东西 - 你结束了与阿拉伯文01/01/2016不等于和正确的一年让我说在沙特阿拉伯,我认为是类似于1354或在泰国2056或什么的情况下......
基本上我得出结论,java的语言环境版本是不完整的https://mvnrepository.com/artifact/com.ibm.icu/icu4j是你需要什么,看起来好像覆盖了所有的语言环境。我结束了一半,一半然后意识到icu4做到了这一切 – Vahid