2010-10-24 25 views
110

我知道这会给我这个月的一天,一个数(112123):如何格式化当月的某天以说明“11th”,“21st”或“23rd”(有序指示符)?

SimpleDateFormat formatDayOfMonth = new SimpleDateFormat("d"); 

但你如何格式化月份的一天,包括ordinal indicator,说11th21st23rd

+7

作为参考,这些被称为序数 - http://en.wikipedia.org/wiki/Ordinal_number_(linguistics )。 – ocodo 2010-10-25 01:23:08

+4

只是为了记录,任何构建响应而不是在表中查找_whole_答案的东西几乎不可能本地化为其他语言。 – 2010-10-25 02:58:13

+1

答案有点不正确,请看我的回答plz。 – J888 2013-07-31 03:15:13

回答

139
// 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"; 
    } 
} 

表:

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

每评论通过@托尔比约恩-Ravn的安徒生,像这样的表本地化时很有帮助来自@kaliatech是很好的,但是因为重复了相同的信息,它会为错误提供机会。在7tn,17tn27tn这个表中实际存在这样的错误(由于StackOverflow的流动特性,此错误可能会随着时间的推移而得到修复,因此请检查the version history on the answer以查看错误)。

+1

是的,但@kaliatech可以修复他的表格,而您的算法无法调整以正确处理月份的第11,12,13个月。 – 2010-10-25 00:52:29

+28

它真的感觉像是简单的数据格式的疏忽,不是吗? – stevevls 2011-12-11 14:11:55

+14

我很喜欢这不是内置的... – jahroy 2013-07-16 20:50:09

47

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]; 

或者使用日历:

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" }; 
+6

如果让表格包含完整的“第21”,“第23”,“第29”,它可以被外化并本地化为其他语言。对于可能成为需求的成功软件。 – 2010-10-25 02:59:44

13
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)]; 
} 
2

这样做有一个更简单和可靠的方法。你需要使用的函数是getDateFromDateString(dateString);它基本上删除日期字符串的st/nd/rd/th并简单地解析它。你可以改变你的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; 

}

+0

本答案是关于*解析*字符串,而问题是关于*生成*字符串。但仍然适合,因为它可能需要两个方向。此外,此答案解决[此其他问题](http://stackoverflow.com/q/33389982/642706)。 – 2015-10-28 18:38:59

29
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"; 
    } 
} 
-8
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"; 
    } 
} 
+1

即使你的代码为11,你的代码也会给出“st”。 – Srinivas 2013-01-14 05:00:45

+0

“12”为“12”。 – Zyerah 2013-01-14 05:02:46

+0

11,12,13日 – Sarz 2015-11-05 09:23:49

2

与格雷格提供的解决方案唯一的问题是,它并没有考虑与结束“青少年”的数字大于100的数字。例如,111应该是第111,而不是第111。这是我的解决方案:

/** 
* Return ordinal suffix (e.g. '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"; 
    } 
} 
+6

在什么情况下,日月序列会超过31天? – SatanEnglish 2014-01-30 21:58:30

+0

@SatanEnglish,这种静态工厂方法的好处在于它不仅可以用于获取一个月的后缀。 :) – 2015-05-15 23:31:20

+1

此方法返回st为11,nd为12和rd为13 – TheIT 2015-06-08 18:37:33

-3

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

要将日期更改为序号,您需要使用以下suffix

DD +  TH = DDTH result >>>> 4TH 

OR to spell the number add SP to the format 

DD + SPTH = DDSPTH result >>> FOURTH 

找到我完成了答案this问题。

+0

问题是在Java格式不Oracle数据库 http://docs.oracle.com/cd/B12037_01/server.101/b10759/sql_elements004.htm#BABGDDFB 的Java使用的SimpleDateFormat日期: https://开头docs.oracle.com/javase/tutorial/i18n/format/simpleDateFormat.html – 2015-08-25 10:50:59

6

如果您试图了解i18n,解决方案会变得更加复杂。

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

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

+0

关于俄罗斯性别的好处,但是如果没有额外的上下文,这在技术上会使%MMM无法实现。 – 2018-01-25 01:22:37

3

这里的许多例子将不适用于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"; 
} 
-3

以下方法可用于获取传入其中的日期的格式化字符串。它将格式化日期以说明第1,第2,第3,第4 ...在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); 
     } 
+2

11日,12日,13日 – Sarz 2015-11-05 09:13:40

8

问题不大。由于这个问题非常嘈杂,所以发布了我用静态方法解决的问题。只需复制,粘贴并使用它!

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); 
    } 

为了测试purose

示例:从主要方法调用它!

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)); 
     } 

输出:

22nd of February 2018 
23rd of February 2018 
24th of February 2018 
25th of February 2018 
26th of February 2018 
27th of February 2018 
28th of February 2018 
1st of March 2018 
2nd of March 2018 
3rd of March 2018 
4th of March 2018 
5th of March 2018 
6th of March 2018 
7th of March 2018 
8th of March 2018 
9th of March 2018 
10th of March 2018 
11th of March 2018 
12th of March 2018 
13th of March 2018 
14th of March 2018 
15th of March 2018 
16th of March 2018 
17th of March 2018 
18th of March 2018 
19th of March 2018 
20th of March 2018 
21st of March 2018 
22nd of March 2018 
23rd of March 2018 
24th of March 2018 
25th of March 2018 
1

我不能答复呼吁基于手动格式英语,唯一的解决方案来满足。我一直在寻找一个适当的解决方案,现在我终于找到了。您应该使用RuleBasedNumberFormat。它完美的工作,并尊重Locale。

0

在科特林你可以使用这样

fun changeDateFormats(currentFormat: String, dateString: String): String { 
     var result = "" 
     try { 
      val formatterOld = SimpleDateFormat(currentFormat, Locale.getDefault()) 
      formatterOld.timeZone = TimeZone.getTimeZone("UTC") 

      var date: Date? = null 

      date = formatterOld.parse(dateString) 

      val dayFormate = SimpleDateFormat("d", Locale.getDefault()) 
      var day = dayFormate.format(date) 

      val formatterNew = SimpleDateFormat("hh:mm a, d'" + getDayOfMonthSuffix(day.toInt()) + "' MMM yy", Locale.getDefault()) 

      if (date != null) { 
       result = formatterNew.format(date) 
      } 

     } catch (e: ParseException) { 
      e.printStackTrace() 
      return dateString 
     } 

     return result 
    } 


    private fun getDayOfMonthSuffix(n: Int): String { 
     if (n in 11..13) { 
      return "th" 
     } 
     when (n % 10) { 
      1 -> return "st" 
      2 -> return "nd" 
      3 -> return "rd" 
      else -> return "th" 
     } 
    } 

一套这样

txt_chat_time_me.text = changeDateFormats("SERVER_DATE", "DATE")