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

lu *_*uan 4 android locale jodatime datetime-format

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

DateTimeFormatter dateFormatter = DateTimeFormat.longDate();
String startTimeStr = dateFormatter.print(localStartTime);
Run Code Online (Sandbox Code Playgroud)

变量的值是:

localStartTime={org.joda.time.LocalDateTime@830018681648}"2013-04-06T23:54:35.000"
startTimeStr={java.lang.String@830018688880}"2013?4?6?"
Run Code Online (Sandbox Code Playgroud)

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

DateTimeFormatter monDayFormatter = DateTimeFormat.forPattern("MMMd");
String startTimeStr = monDayFormatter.print(localStartTime);
Run Code Online (Sandbox Code Playgroud)

变量的值是:

localStartTime={org.joda.time.LocalDateTime@830018681648}"2013-04-06T23:54:35.000"
startTimeStr={java.lang.String@830018683220}"4?6"
Run Code Online (Sandbox Code Playgroud)

我的期望startTimeStr是什么4?6?.这里汉字?= Day.我不想将模式硬编码为"MMMd日",因为它应该根据当前的语言环境信息进行自我调整.任何帮助将不胜感激.

Men*_*ild 5

在unicode联盟的网站上,您将在中文CLDR存储库中找到以下条目(日历类型=格里高利):

<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>
Run Code Online (Sandbox Code Playgroud)

在内部,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?
Run Code Online (Sandbox Code Playgroud)

这段代码:

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?
Run Code Online (Sandbox Code Playgroud)

然后你得到你想要的.虽然你写道:

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

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

2016-12-06更新:

Joda-Time没有改变任何语言环境的通用月 - 日模式的情况.不幸的是Joda-Time的官方继任者,JSR-310(java.time-package)也管理得不好,请参阅JDK-issue 8168532.这足以让我在平均时间内找到我自己的时间库Time4J的解决方案.对CLDR数据的密切分析表明,还有其他日期格式可用于许多语言,但在不同的部分可通过一组字段访问.键"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
Run Code Online (Sandbox Code Playgroud)

这也是值得大家注意的是,地方不能建设格式化后的一个合理的方式,因为本地化的模式结构施工期间,冻结,不再明智.后来语言环境的改变而改变.但是,这将在未来的版本中得到改进.