如何在Java中使用不受支持的Locale

时间:2017-02-16 07:19:29

标签: java locale date-formatting icu4j

作为国际化的一部分,需要支持少数国家 像

安提瓜和巴布达 - ISO3166代码 - AG& 多米尼加共和国 - ISO3166代码 - DO

    Locale loc = new Locale("en", "AG");
    DateFormat df1 = DateFormat.getDateInstance(DateFormat.SHORT, loc); 
    System.out.println("Short format: " + df1.format(new Date()));

Java将以mm / dd / yy格式显示日期,其中这些国家/地区的日期格式为dd / mm / yy。

我们有什么方法可以达到dd / mm / yy的模式吗? 甚至ICU4J图书馆也不支持这些国家?

提前致谢

2 个答案:

答案 0 :(得分:5)

您可以通过基于相应的服务提供者接口(SPI)创建扩展来将其他语言环境添加到Java运行时。

例如,如果要为Antigua和Barbuda(en_AG)指定短日期格式,可以按如下方式实现java.text.spi.DateFormatProvider SPI:

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.spi.DateFormatProvider;
import java.util.Locale;

public class EnAgDateFormatProvider extends DateFormatProvider {
    private static final Locale EN_AG_LOCALE = new Locale("en", "AG");

    public DateFormat getDateInstance(int style, Locale locale) {
        // if your extension supports multiple locales, you have to take the locale
        // parameter into account as well
        switch (style) {
            case DateFormat.SHORT:
                return new SimpleDateFormat("dd/MM/yy");

            default:
                // TODO implement other styles
                return null;
        }
    }

    public DateFormat getTimeInstance(int style, Locale locale) {
        // TODO implement this method
        return null;
    }

    public DateFormat getDateTimeInstance(int dateStyle, int timeStyle,
            Locale locale) {

        // TODO implement this method
        return null;
    }

    public Locale[] getAvailableLocales() {
        return new Locale[]{EN_AG_LOCALE};
    }
}

这需要打包在JAR文件中,在JAR的META-INF/services目录中,您需要创建一个名为java.text.spi.DateFormatProvider的文件。该文件需要包含提供者的完全限定名称,仅在我的情况下:

EnAgDateFormatProvider

创建JAR后,需要将其放在JRE的extensions目录中。在我的Ubuntu机器上,这恰好是/usr/lib/jvm/java-8-oracle/jre/lib/ext/

之后,您问题的代码段:

Locale loc = new Locale("en", "AG");
DateFormat df1 = DateFormat.getDateInstance(DateFormat.SHORT, loc); 
System.out.println("Short format: " + df1.format(new Date()));

将打印出来:

Short format: 16/02/2017

参考文献:

答案 1 :(得分:2)

你正在使用麻烦的旧日期时间类,现在是旧的,取而代之的是java.time类。

安提瓜和巴布达

“安提瓜和巴布达 - ISO3166代码 - AG”在Java 8中不是受支持的语言环境。请参阅list of supported locales或致电:

System.out.println ( "locales: " + Arrays.toString ( Locale.getAvailableLocales () ) );

您可以为此类不受支持的区域设置构建自己的显式格式设置模式列表。例如,DateTimeFormatter.ofPattern( "dd/MM/yy" )

更好的是,使用语言国家字符串(例如“en-AG”)定义每个未定义语言环境的Map到使用相同适当格式的类似定义Locale

或者为每个未定义的语言环境定义Enum,使用为每个长度返回DateTimeFormatter个对象的方法(FULL,SHORT等)。

或者考虑一下Answer by Comelissen,虽然我还没有很好地研究它以便推荐它。

多米尼加共和国

“Java 8中支持多米尼加共和国 - ISO3166代码 - DO”

Locale locale = new Locale ( "es" , "DO" ); // Spanish in Dominican Republic.
LocalDate localDate = LocalDate.now ( ZoneId.of ( "Europe/Paris" ) );
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate ( FormatStyle.SHORT ).withLocale ( locale );
String output = localDate.format ( f );

System.out.println ( "localDate: " + localDate + " is " + output );
  

localDate:2017-02-16是16/02/17

结果如您所愿,dd / MM / yy。

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore