如何获取月和日的区域设置日期格式

时间:2014-02-09 16:25:52

标签: android locale jodatime datetime-format

我使用Joda Time格式化dateTime,如下所示:

DateTimeFormatter dateFormatter = DateTimeFormat.longDate();
String startTimeStr = dateFormatter.print(localStartTime);

变量的值为:

localStartTime={org.joda.time.LocalDateTime@830018681648}"2013-04-06T23:54:35.000"
startTimeStr={java.lang.String@830018688880}"2013年4月6日"

问题是如何在月和日获得区域设置日期格式?我尝试过以下代码:

DateTimeFormatter monDayFormatter = DateTimeFormat.forPattern("MMMd");
String startTimeStr = monDayFormatter.print(localStartTime);

并且变量的值为:

localStartTime={org.joda.time.LocalDateTime@830018681648}"2013-04-06T23:54:35.000"
startTimeStr={java.lang.String@830018683220}"4月6"

我的预期startTimeStr4月6日。中文字符 = Day。 我不想将模式硬编码为“MMMd日”,因为它应该根据当前的语言环境信息进行自我调整。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:5)

在unicode联盟的网站上,你会发现中文CLDR repository例如条目如下(日历类型=格里高利):

<dateFormats>
  <dateFormatLength type="full">
     <dateFormat>
    <pattern>y年M月d日EEEE</pattern>
     </dateFormat>
  </dateFormatLength>
  <dateFormatLength type="long">
     <dateFormat>
        <pattern>y年M月d日</pattern>
     </dateFormat>
  </dateFormatLength>
  <dateFormatLength type="medium">
     <dateFormat>
       <pattern>y年M月d日</pattern>
     </dateFormat>
  </dateFormatLength>
  <dateFormatLength type="short">
     <dateFormat>
       <pattern>yy/M/d</pattern>
     </dateFormat>
  </dateFormatLength>
</dateFormats>

在JodaTime或JDK dateformat类中,每个本地化的日期格式都将被转换为这样的模式 - 包括像“日”这样的文字。 CLDR没有定义仅限月 - 日的格式,但这只是一般年 - 月 - 日格式的一部分,因此如果您用作

的替代品
DateTimeFormatter dateFormatter = DateTimeFormat.longDate().withLocale(Locale.CHINESE);
LocalDateTime localStartTime = new LocalDateTime(2013,4,6,23,54,35);
String startTimeStr = dateFormatter.print(localStartTime);
System.out.println(startTimeStr); // output: 2013年4月6日

此代码:

DateTimeFormatter dateFormatter = DateTimeFormat.forPattern("M月d日");
LocalDateTime localStartTime = new LocalDateTime(2013,4,6,23,54,35);
String startTimeStr = dateFormatter.print(localStartTime);
System.out.println(startTimeStr); // output: 4月6日
然后你得到了你想要的东西。虽然你写道:

我不想将模式硬编码为“MMMd日”

这几乎与库内部完成的程序相同。因此,通过选择适当的文字来对模式本身进行本地化。没有办法从CLDR中提取没有年份的本地化日期模式。如果你想要这个,那么你必须为不同的语言环境管理你自己的一组本地化的月日模式,可能在Map&lt; Locale,String&gt;中。

2016-12-06更新:

Joda-Time没有改变任何语言环境的通用月 - 日模式的情况。不幸的是,Joda-Time的官方继任者,JSR-310(java.time - 包)也不能很好地管理它,请参阅JDK-issue 8168532。这足以让我在平均时间内找到我自己的时间库Time4J的解决方案。对CLDR数据的详细分析表明,还有其他日期格式适用于多种语言,但在不同的部分accessible via a group of fields。键“Md”,“MMMd”和“MMMMd”与您的用例相关。 Time4J中的示例(在未来的版本中,JSR-310也应该得到支持):

    PlainTimestamp tsp = Iso8601Format.EXTENDED_DATE_TIME.parse("2013-04-06T23:54:35.000");
    AnnualDate ad = AnnualDate.of(tsp.getMonth(), tsp.getDayOfMonth());
    ChronoFormatter<AnnualDate> chinese =
        ChronoFormatter.ofStyle(DisplayMode.LONG, Locale.CHINESE, AnnualDate.chronology());
    ChronoFormatter<AnnualDate> english =
        ChronoFormatter.ofStyle(DisplayMode.LONG, Locale.ENGLISH, AnnualDate.chronology());
    System.out.println(chinese.format(ad)); // 4月6日
    System.out.println(english.format(ad)); // Apr 6

还值得注意的是,在构造格式化程序后以合理的方式无法更改语言环境,因为本地化的模式结构将在构造期间冻结,并且不再适用于以后更改语言环境。但是,这将在未来的版本中得到改进。

答案 1 :(得分:2)

你走了:

    Calendar calendar = Calendar.getInstance();
    SimpleDateFormat day_week = new SimpleDateFormat("EEEE");
    SimpleDateFormat month_date = new SimpleDateFormat("MMMMMMMMM");
    Date d = new Date();
    String dayOfTheWeek = day_week.format(d);
    String month = month_date.format(calendar.getTime());

希望它有所帮助。

答案 2 :(得分:0)

实际上,Android提供了一个辅助类来处理UTS #35格式android.text.format.DateFormat

尤其是在这种情况下,自API级别18起DateFormat.getBestDateTimePattern(locale, skeleton)

所以我们可以简化这样的事情:

String bestFormat = DateFormat.getBestDateTimePattern(Locale.getDefault(), "MMMd");
String formatted = DateFormat.format(bestFormat, System.currentTimeMillis()).toString();

formatted为“ 12月19日”。

该行为已在Android Q和Android O上得到确认。