你如何在Java中设置“11th”,“21st”或“23rd”的月份? (有序指标)

我知道这会给我一个月的一天( 23 ):

 SimpleDateFormat formatDayOfMonth = new SimpleDateFormat("d"); 

但是,如何在一个月的日子里设置一个序数指标 ,比如说Java中的11th 21st23rd呢?

 // https://github.com/google/guava import static com.google.common.base.Preconditions.*; String getDayOfMonthSuffix(final int n) { checkArgument(n >= 1 && n <= 31, "illegal day of month: " + n); if (n >= 11 && n <= 13) { return "th"; } switch (n % 10) { case 1: return "st"; case 2: return "nd"; case 3: return "rd"; default: return "th"; } } 

来自@kaliatech的表格很好,但是由于重复了相同的信息,这就为错误提供了机会。 这样的错误实际上存在于7tn17tn27tn的表中(由于StackOverflow的stream动特性,这个错误可能会随着时间的推移而得到修复,所以请查看答案上的版本历史以查看错误)。

JDK没有这样做。

  static String[] suffixes = // 0 1 2 3 4 5 6 7 8 9 { "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th", // 10 11 12 13 14 15 16 17 18 19 "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", // 20 21 22 23 24 25 26 27 28 29 "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th", // 30 31 "th", "st" }; Date date = new Date(); SimpleDateFormat formatDayOfMonth = new SimpleDateFormat("d"); int day = Integer.parseInt(formatDateOfMonth.format(date)); String dayStr = day + suffixes[day]; 

或使用日历:

  Calendar c = Calendar.getInstance(); c.setTime(date); int day = c.get(Calendar.DAY_OF_MONTH); String dayStr = day + suffixes[day]; 

根据@thorbjørn-ravn-andersen的评论,这样的表格在本地化时可能会有帮助:

  static String[] suffixes = { "0th", "1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", "10th", "11th", "12th", "13th", "14th", "15th", "16th", "17th", "18th", "19th", "20th", "21st", "22nd", "23rd", "24th", "25th", "26th", "27th", "28th", "29th", "30th", "31st" }; 
 private String getCurrentDateInSpecificFormat(Calendar currentCalDate) { String dayNumberSuffix = getDayNumberSuffix(currentCalDate.get(Calendar.DAY_OF_MONTH)); DateFormat dateFormat = new SimpleDateFormat(" d'" + dayNumberSuffix + "' MMMM yyyy"); return dateFormat.format(currentCalDate.getTime()); } private String getDayNumberSuffix(int day) { if (day >= 11 && day <= 13) { return "th"; } switch (day % 10) { case 1: return "st"; case 2: return "nd"; case 3: return "rd"; default: return "th"; } } 
 String ordinal(int num) { String[] suffix = {"th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"}; int m = num % 100; return String.valueOf(num) + suffix[(m > 10 && m < 20) ? 0 : (m % 10)]; } 

问题不大。 由于这个问题是非常嘈杂,所以张贴我已经解决了简单的静态方法。 只需复制并粘贴!

  public static String getFormattedDate(Date date){ Calendar cal=Calendar.getInstance(); cal.setTime(date); //2nd of march 2015 int day=cal.get(Calendar.DATE); if(!((day>10) && (day<19))) switch (day % 10) { case 1: return new SimpleDateFormat("d'st' 'of' MMMM yyyy").format(date); case 2: return new SimpleDateFormat("d'nd' 'of' MMMM yyyy").format(date); case 3: return new SimpleDateFormat("d'rd' 'of' MMMM yyyy").format(date); default: return new SimpleDateFormat("d'th' 'of' MMMM yyyy").format(date); } return new SimpleDateFormat("d'th' 'of' MMMM yyyy").format(date); } 

用于检测嘌呤

从main方法调用这个!

 Date date = new Date(); Calendar cal=Calendar.getInstance(); cal.setTime(date); for(int i=0;i<32;i++){ System.out.println(getFormattedDate(cal.getTime())); cal.set(Calendar.DATE,(cal.getTime().getDate()+1)); } 

如果你试图意识到国际化,解决scheme会变得更加复杂。

问题在于,在其他语言中,后缀不仅取决于数字本身,而且还取决于它的名词。 例如在俄语中,它将是“2-ойдень”,而是“2-аянеделя”(这些意思是“第2天”,而是“第2周”)。 如果我们只格式化date,这不适用,但在更通用的情况下,您应该了解复杂性。

我认为很好的解决scheme(我没有时间去实际实现)将扩展SimpleDateFormetter应用本地感知MessageFormat传递给父类之前。 这样你就可以支持3月格式%M获得“3”,%MM获得“03-rd”和%MMM获得“3”。 从这个类看起来像普通的SimpleDateFormatter,但支持更多的格式。 另外,如果这个模式被错误的SimpleDateFormetter应用,结果会被错误地格式化,但是仍然可读。

只有格雷格提供的解决scheme的问题是,它不包括大于100的数字与“青less年”数字结束。 例如,111应该是第111,而不是第111。 这是我的解决scheme:

 /** * Return ordinal suffix (eg 'st', 'nd', 'rd', or 'th') for a given number * * @param value * a number * @return Ordinal suffix for the given number */ public static String getOrdinalSuffix( int value ) { int hunRem = value % 100; int tenRem = value % 10; if ( hunRem - tenRem == 10 ) { return "th"; } switch ( tenRem ) { case 1: return "st"; case 2: return "nd"; case 3: return "rd"; default: return "th"; } } 

这里的许多例子将不会为11,12,13工作。这是更通用的,将适用于所有情况。

 switch (date) { case 1: case 21: case 31: return "" + date + "st"; case 2: case 22: return "" + date + "nd"; case 3: case 23: return "" + date + "rd"; default: return "" + date + "th"; } 

有一个更简单和可靠的方法来做到这一点。 你需要使用的函数是getDateFromDateString(dateString); 它基本上删除datestring的st / nd / rd / th,并简单地parsing它。 你可以改变你的SimpleDateFormat任何东西,这将工作。

 public static final SimpleDateFormat sdf = new SimpleDateFormat("d"); public static final Pattern p = Pattern.compile("([0-9]+)(st|nd|rd|th)"); private static Date getDateFromDateString(String dateString) throws ParseException { return sdf.parse(deleteOrdinal(dateString)); } private static String deleteOrdinal(String dateString) { Matcher m = p.matcher(dateString); while (m.find()) { dateString = dateString.replaceAll(Matcher.quoteReplacement(m.group(0)), m.group(1)); } return dateString; 

}

我不能满足于要求基于手册格式的英文解决scheme的答案。 我一直在寻找一个适当的解决scheme,现在我终于find了。

您应该使用RuleBasedNumberFormat 。 它完美的工作,并尊重的地方。

以下是对问题的更有效的回答,而不是对风格进行硬编码。

要将date更改为序号,您需要使用以下后缀 。

 DD + TH = DDTH result >>>> 4TH OR to spell the number add SP to the format DD + SPTH = DDSPTH result >>> FOURTH 

在这个问题find我完成的答案。

下面的方法可以用来获取传递给它的date的格式化string。 它将格式化date说第一,第二,第三,第四..在Java中使用SimpleDateFormat。 例如: – 2015年9月1日

 public String getFormattedDate(Date date){ Calendar cal=Calendar.getInstance(); cal.setTime(date); //2nd of march 2015 int day=cal.get(Calendar.DATE); switch (day % 10) { case 1: return new SimpleDateFormat("d'st' 'of' MMMM yyyy").format(date); case 2: return new SimpleDateFormat("d'nd' 'of' MMMM yyyy").format(date); case 3: return new SimpleDateFormat("d'rd' 'of' MMMM yyyy").format(date); default: return new SimpleDateFormat("d'th' 'of' MMMM yyyy").format(date); } 
 public String getDaySuffix(int inDay) { String s = String.valueOf(inDay); if (s.endsWith("1")) { return "st"; } else if (s.endsWith("2")) { return "nd"; } else if (s.endsWith("3")) { return "rd"; } else { return "th"; } } 
    Interesting Posts