根据语言环境

时间:2018-12-10 12:11:03

标签: java android simpledateformat

我想格式化一个日期,该日期应该本地化并包括“日期间”。

“白天”不是上午/下午,而是“下午”,“清晨”等。

已启用12小时设置的基于德语语言环境的格式化日期应类似于03.08.18, 9:01 abends,“结束”表示晚上。

同一个示例应该是西班牙语的3/8/18 9:01 de la noche


为什么我认为应该可行

A:因为WhatsApp Android应用格式的日期是这样的

B:因为Java 10源代码包含以下内容(来自德语翻译文件):

<dayPeriods>
<dayPeriodContext type="format">
    <dayPeriodWidth type="wide">
        <dayPeriod type="afternoon">nachmittags</dayPeriod>
        <dayPeriod type="am">vorm.</dayPeriod>
        <dayPeriod type="earlyMorning">morgens</dayPeriod>
        <dayPeriod type="evening">abends</dayPeriod>
        <dayPeriod type="morning">vormittags</dayPeriod>
        <dayPeriod type="night">nachts</dayPeriod>
        <dayPeriod type="noon">Mittag</dayPeriod>
        <dayPeriod type="pm">nachm.</dayPeriod>
    </dayPeriodWidth>
</dayPeriodContext>
...
</dayPeriods>


我尝试过 :(当前为语言环境)

DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, current);

String formattedDate = df.format(System.currentTimeMillis());

输出:08.12.18 7:24 nachm8/12/18 7:54 p. m.


以下代码具有相同的输出:

DateFormat abc = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, current);

abc.format(System.currentTimeMillis());


我还尝试了DateTimeFormatterBuilder(使用所有AMPM_OF_DAY版本):

DateTimeFormatter test = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.SHORT);

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
                .append(test)
                .appendText(ChronoField.AMPM_OF_DAY, TextStyle.SHORT)
                .appendText(ChronoField.AMPM_OF_DAY, TextStyle.NARROW)
                .appendText(ChronoField.AMPM_OF_DAY, TextStyle.FULL)
                .appendText(ChronoField.AMPM_OF_DAY, TextStyle.FULL_STANDALONE)
                .toFormatter(current);

ZonedDateTime date = ZonedDateTime.now();
date.format(fmt);

输出:8 dic. 2018 19:54p. m.p. m.p. m.11


我可以通过这种方式输出日期吗?

谢谢

1 个答案:

答案 0 :(得分:2)

只有两个支持白天的库,即ICU4J(部分并入Android)和我的lib Time4A。 java.text.DateFormatjava.time.format.DateTimeFormatter之类的其他格式化程序不受支持。

Time4A中针对德国语言环境的示例(此处与老式类型java.util.Date的桥梁):

 ChronoFormatter<java.util.Date> f =
      ChronoFormatter.ofPattern(
          "dd.MM.uuuu, h:mm BBBB",
          PatternType.CLDR,
          Locale.GERMAN,
          Moment.axis(TemporalType.JAVA_UTIL_DATE))
      .withStdTimezone();
 System.out.println(f.format(new java.util.Date()));

示例输出=>“ 11.12.2018,6:03 morgens”

它使用由CLDR数据的LDML语法定义的special pattern symbol "B"(由Unicode联盟管理)。日分区规则也从CLDR数据中获取,并像下面这样查找德语:

# day-period-rules
T0000=night1
T0500=morning1
T1000=morning2
T1200=afternoon1
T1300=afternoon2
T1800=evening1

# day-period-translations
P(a)_morning1=morgens
P(a)_morning2=vormittags
P(a)_afternoon1=mittags
P(a)_afternoon2=nachmittags
P(a)_evening1=abends
P(a)_night1=nachts

如果您不同意这些数据,则可以通过builder pattern构建自己的自定义格式化程序。

关于ICU4J的注意事项:我尚未测试过lib,但也许它的类com.ibm.icu.text.SimpleDateFormat也支持模式符号B(但是javadoc已过时)。

另一个说明:

如果您喜欢基于样式的格式设置而没有指定具体的模式,则可以使用日期和时间部分的组合方式:

    Locale loc = Locale.US;

    // our concrete values to be formatted
    Moment moment = SystemClock.currentMoment();
    PlainDate calendarDate = moment.toLocalTimestamp().getCalendarDate();

    // get the localized clock pattern
    Map<String, String> textForms = CalendarText.getIsoInstance(loc).getTextForms();
    String pattern = 
            textForms.containsKey("F_Bhm") ? textForms.get("F_Bhm") : "h:mm B";

    // construct the style-based date formatter
    ChronoFormatter<PlainDate> f1 = 
            ChronoFormatter.ofDateStyle(DisplayMode.SHORT, loc);

    // construct the time formatter
    ChronoFormatter<Moment> f2 = ChronoFormatter.ofMomentPattern(
        pattern,
        PatternType.CLDR,
        loc,
        Timezone.ofSystem().getID());

    System.out.println(f1.format(calendarDate) + " " + f2.format(moment));
    // example output => "12/11/18 6:18 in the morning"