[java] Wie formatieren Sie den Tag des Monats, um "11.", "21." oder "23." (Ordinalindikator) zu sagen?



Answers

In JDK gibt es dazu nichts.

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

Oder mit Kalender:

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

Pro Kommentar von @ thorbjørn-ravn-andersen kann eine Tabelle wie diese hilfreich sein beim Lokalisieren:

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

Ich weiß, das wird mir den Tag des Monats als eine Zahl geben ( 11 , 21 , 23 ):

SimpleDateFormat formatDayOfMonth = new SimpleDateFormat("d");

Aber wie formatieren Sie den Tag des Monats, um einen ordinalen Indikator , etwa 11th , 21st oder 23rd , 23rd ?




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



Ich kann nicht zufrieden sein mit den Antworten, die eine auf Englisch basierende Lösung auf der Basis manueller Formate fordern. Ich suche schon seit einiger Zeit nach einer richtigen Lösung und habe sie endlich gefunden.

Sie sollten RuleBasedNumberFormat . Es funktioniert perfekt und respektiert das Gebietsschema.




Das Folgende ist eine effizientere Antwort auf die Frage, anstatt den Stil hart zu kodieren.

Um den Tag in die Ordnungszahl zu ändern, müssen Sie das folgende suffix .

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

OR to spell the number add SP to the format

DD + SPTH = DDSPTH   result >>> FOURTH

Finden Sie meine vollständige Antwort in suffix Frage.




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 > 3 && m < 21) ? 0 : (m % 10)];
}



Wenn Sie versuchen, auf i18n zu achten, wird die Lösung noch komplizierter.

Das Problem ist, dass in anderen Sprachen das Suffix nicht nur von der Zahl selbst abhängen kann, sondern auch von dem Nomen, auf das es sich bezieht. Zum Beispiel in Russisch wäre es "2-ой день", aber "2-ая неделя" (diese bedeuten "2. Tag", aber "2. Woche"). Dies gilt nicht, wenn wir nur Tage formatieren, aber in einem etwas allgemeineren Fall sollten Sie sich der Komplexität bewusst sein.

Ich denke, nette Lösung (ich hatte keine Zeit, tatsächlich zu implementieren) wäre, SimpleDateFormetter zu erweitern, um Local-aware MessageFormat anzuwenden, bevor es an die Elternklasse übergeben wird. Auf diese Weise könnten Sie zum Beispiel für März-Formate% M unterstützen, um "3-rd" zu erhalten,% MM, um "03-rd" zu erhalten und% MMM, um "dritte" zu erhalten. Von außen sieht diese Klasse wie reguläres SimpleDateFormatter aus, unterstützt aber mehr Formate. Auch wenn dieses Muster fälschlicherweise vom regulären SimpleDateFormetter angewendet würde, wäre das Ergebnis falsch formatiert, aber immer noch lesbar.




In Kotlin können Sie so verwenden

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

so eingestellt

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



Das einzige Problem mit der von Greg bereitgestellten Lösung besteht darin, dass die Nummer nicht größer als 100 ist, wenn die "Teen" -Nummern enden. Zum Beispiel sollte 111 111 sein, nicht 111. Das ist meine Lösung:

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



Related