2017-04-17 12 views
2

我一直在试图让Java根据它们的区域设置来转换数字 来自this post这帮助了很大的帮助,因为在理解之前我已经设计了自己的方法来将数字转换为具体地点(按有关此主题的其他混乱的讨论)java Locale.Builder setExtension(Locale.UNICODE_LOCALE_EXTENSION

因此,假设我有:

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 =数量ca-language =日历

但运行时:

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

要回答我的问题你可以bu从这里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数= -nu和一个从去年小写-hebr给你'el-GR-u-nu-grek'希腊或同为希伯来语'iw-IL-u-n-hebr'

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

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

+0

基本上我得出结论,java的语言环境版本是不完整的https://mvnrepository.com/artifact/com.ibm.icu/icu4j是你需要什么,看起来好像覆盖了所有的语言环境。我结束了一半,一半然后意识到icu4做到了这一切 – Vahid

回答

0

回答我自己的问题,因为这是一个复杂的话题,没有很好地解释。

简而言之,根据我的评论,你可能更好使用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或什么的情况下......