How do you format the day of the month to say “11th”, “21st” or “23rd” (ordinal indicator)?

后端 未结 20 983
逝去的感伤
逝去的感伤 2020-11-22 02:41

I know this will give me the day of the month as a number (11, 21, 23):

SimpleDateFormat formatDayOfMonth = new Simple         


        
相关标签:
20条回答
  • 2020-11-22 02:50

    Only issue with the solution provided by Greg is that it does not account for number greater than 100 with the "teen" numbers ending. For example, 111 should be 111th, not 111st. This is my solution:

    /**
     * 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";
        }
    }
    
    0 讨论(0)
  • 2020-11-22 02:52

    RuleBasedNumberFormat in ICU library

    I appreciated the link to the ICU project's library from @Pierre-Olivier Dybman (http://www.icu-project.org/apiref/icu4j/com/ibm/icu/text/RuleBasedNumberFormat.html), however still had to figure out how to use it, so an example of the RuleBasedNumberFormat usage is below.

    It will only format single number rather than the whole date, so you will need to build a combined string if looking for a date in format: Monday 3rd February, for example.

    The below code sets up the RuleBasedNumberFormat as an Ordinal format for a given Locale, creates a java.time ZonedDateTime, and then formats the number with its ordinal into a string.

    RuleBasedNumberFormat numOrdinalFormat = new RuleBasedNumberFormat(Locale.UK,
        RuleBasedNumberFormat.ORDINAL);
    ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Pacific/Auckland"));
    
    String dayNumAndOrdinal = numOrdinalFormat.format(zdt.toLocalDate().getDayOfMonth());
    

    Example output:

    3rd

    Or

    4th

    etc.

    0 讨论(0)
  • 2020-11-22 02:53

    Using the new java.time package and the newer Java switch statement, the following easily allows an ordinal to be placed on a day of the month. One drawback is that this does not lend itself to canned formats specified in the DateFormatter class.

    Simply create a day of some format but include %s%s to add the day and ordinal later.

    ZonedDateTime ldt = ZonedDateTime.now();
    String format = ldt.format(DateTimeFormatter
            .ofPattern("EEEE, MMMM '%s%s,' yyyy hh:mm:ss a zzz"));
    

    Now pass the day of the week and the just formatted date to a helper method to add the ordinal day.

    
    int day = ldt.getDayOfMonth();
    System.out.println(applyOrdinalDaySuffix(format, day));
    
    

    Prints

    Tuesday, October 6th, 2020 11:38:23 AM EDT
    

    Here is the helper method.

    Using the Java 14 switch expressions makes getting the ordinal very easy.

    public static String applyOrdinalDaySuffix(String format,
            int day) {
        if (day < 1 || day > 31)
            throw new IllegalArgumentException(
                    String.format("Bad day of month (%s)", day));
        String ord = switch (day) {
            case 1, 21, 31 -> "st";
            case 2, 22 -> "nd";
            case 3, 23 -> "rd";
            default -> "th";
        };
        
        return String.format(format, day, ord);
    }
    
    0 讨论(0)
  • 2020-11-22 02:55

    In kotlin you can use like this

    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"
            }
        }
    

    set like this

      txt_chat_time_me.text = changeDateFormats("SERVER_DATE", "DATE")
    
    0 讨论(0)
  • 2020-11-22 02:55
    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";
      }
    }
    
    0 讨论(0)
  • 2020-11-22 02:56
    // 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";
        }
    }
    

    The table from @kaliatech is nice, but since the same information is repeated, it opens the chance for a bug. Such a bug actually exists in the table for 7tn, 17tn, and 27tn (this bug might get fixed as time goes on because of the fluid nature of StackOverflow, so check the version history on the answer to see the error).

    0 讨论(0)
提交回复
热议问题