Wie formatieren Sie den Tag des Monats mit „11.“, „21.“ oder „23.“ (Ordnungsindikator)?


146

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

SimpleDateFormat formatDayOfMonth = new SimpleDateFormat("d");

Aber wie formatieren Sie den Tag des Monats ein umfassen Ordinalzeichen , sagen wir 11th, 21stoder 23rd?


13
Als Referenz werden diese als Ordnungszahlen bezeichnet ( en.wikipedia.org/wiki/Ordinal_number_(linguistics) .
ocodo

5
Nur zur Veranschaulichung: Es ist nahezu unmöglich , alles, was die Antwort erstellt, anstatt die gesamte Antwort in einer Tabelle nachzuschlagen, in anderen Sprachen zu lokalisieren.
Thorbjørn Ravn Andersen

2
Die Antwort ist irgendwie falsch. Schauen Sie sich meine Antwort an.
J888

2
Moderner Kommentar: Ich empfehle Ihnen, die SimpleDateFormatKlasse zu meiden . Es ist nicht nur lange veraltet, es ist auch notorisch problematisch. Heute haben wir java.timedie moderne Java-API für Datum und Uhrzeit und ihre DateTimeFormatter.
Ole VV

Schauen Sie sich die Zahlen-API an ( math.tools/api/numbers ). Es hat Unterstützung für Ordnungszahl, Kardinal, Zahl in verschiedenen Sprachen geschrieben, als Währung in verschiedenen Sprachen geschrieben usw.
dors

Antworten:


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

Die Tabelle von @kaliatech ist nett, aber da die gleichen Informationen wiederholt werden, besteht die Möglichkeit eines Fehlers. Ein solcher Fehler ist tatsächlich in der Tabelle für 7tn, 17tnund vorhanden 27tn(dieser Fehler kann im Laufe der Zeit aufgrund der fließenden Natur von StackOverflow behoben werden. Überprüfen Sie daher den Versionsverlauf in der Antwort , um den Fehler zu sehen).


36
es fühlt sich wirklich wie ein Versehen im einfachen Datenformat an, nicht wahr?
Stevevls

51
Viel Spaß beim Internationalisieren. : D
Trejkaz

6
@ Trejkaz Außerhalb des Umfangs der Frage :)
Greg Mattes

3
Diese Lösung unterstützt nur Englisch. Verwenden Sie RuleBasedNumberFormat von ICU4J für die lokalisierte Lösung.
Дмитро Яковлєв

7
Ihr seid im Unkraut und der Ton nimmt eine Wendung. Keinen Bedarf. Diese Frage bezog sich nicht auf die Feinheiten der Internationalisierung. Internationalisierung ist sicherlich ein gutes Thema, aber es sollte eine andere Frage mit diesem Schwerpunkt gestellt werden. Ich habe diese Frage immer so interpretiert, dass ich nach einem schnellen und schmutzigen Weg gefragt habe, um dies auf Englisch zu erreichen. Ich schlage daher vor, dass wir, wenn es in der Java-Welt wirklich keine gute, internationalisierungsfreundliche Lösung gibt, ein Projekt starten, z. B. GitHub, und eine gute Lösung erstellen. Lassen Sie mich wissen, wenn Sie interessiert sind.
Greg Mattes

51

In JDK gibt es nichts, was dies tun könnte.

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

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

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

8
Wenn Sie die Tabelle die vollständigen "21.", "23.", "29." enthalten lassen, kann sie externalisiert und in andere Sprachen lokalisiert werden. Für erfolgreiche Software kann dies eine Anforderung werden.
Thorbjørn Ravn Andersen

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

Ich habe gerade Ihre Lösung ausprobiert, während ich die einfachen Anführungszeichen in der Musterzeichenfolge weggelassen habe, die dem SimpleDateFormat-Konstruktor bereitgestellt wurde. Ich verstehe jetzt, warum sie da sind. Ich bekomme ein java.lang.IllegalArgumentExceptionwegen "eines illegalen Mustercharakters, t."
typisch danny

17

Frage ist wenig alt. Da diese Frage sehr laut ist, poste ich, was ich mit der statischen Methode als Util gelöst habe. Einfach kopieren, einfügen und verwenden!

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

Zum Testen von Purose

Beispiel: Aufruf von der Hauptmethode!

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

Ausgabe:

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

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

14

Ich möchte die moderne Antwort beitragen. Die SimpleDateFormatKlasse konnte verwendet werden, als die Frage vor 8 Jahren gestellt wurde, aber Sie sollten sie jetzt vermeiden, da sie nicht nur längst veraltet, sondern auch notorisch problematisch ist. Verwenden Sie java.timestattdessen.

Bearbeiten

DateTimeFormatterBuilder.appendText(TemporalField, Map<Long, String>)ist großartig für diesen Zweck. Damit erstellen wir einen Formatierer, der die Arbeit für uns erledigt:

    Map<Long, String> ordinalNumbers = new HashMap<>(42);
    ordinalNumbers.put(1L, "1st");
    ordinalNumbers.put(2L, "2nd");
    ordinalNumbers.put(3L, "3rd");
    ordinalNumbers.put(21L, "21st");
    ordinalNumbers.put(22L, "22nd");
    ordinalNumbers.put(23L, "23rd");
    ordinalNumbers.put(31L, "31st");
    for (long d = 1; d <= 31; d++) {
        ordinalNumbers.putIfAbsent(d, "" + d + "th");
    }

    DateTimeFormatter dayOfMonthFormatter = new DateTimeFormatterBuilder()
            .appendText(ChronoField.DAY_OF_MONTH, ordinalNumbers)
            .appendPattern(" MMMM")
            .toFormatter();

    LocalDate date = LocalDate.of(2018, Month.AUGUST, 30);
    for (int i = 0; i < 6; i++) {
        System.out.println(date.format(dayOfMonthFormatter));
        date = date.plusDays(1);
    }

Die Ausgabe dieses Snippets lautet:

30th August
31st August
1st September
2nd September
3rd September
4th September

Alte Antwort

Dieser Code ist kürzer, aber meiner Meinung nach nicht so elegant.

    // ordinal indicators by numbers (1-based, cell 0 is wasted)
    String[] ordinalIndicators = new String[31 + 1];
    Arrays.fill(ordinalIndicators, 1, ordinalIndicators.length, "th");
    ordinalIndicators[1] = ordinalIndicators[21] = ordinalIndicators[31] = "st";
    ordinalIndicators[2] = ordinalIndicators[22] = "nd";
    ordinalIndicators[3] = ordinalIndicators[23] = "rd";

    DateTimeFormatter dayOfMonthFormatter = DateTimeFormatter.ofPattern("d");

    LocalDate today = LocalDate.now(ZoneId.of("America/Menominee")).plusWeeks(1);
    System.out.println(today.format(dayOfMonthFormatter) 
                        + ordinalIndicators[today.getDayOfMonth()]);

Ich habe gerade dieses Snippet ausgeführt

23 ..

Eines der vielen Merkmale von java.timeist, dass es einfach und zuverlässig ist, den Tag des Monats als zu erhalten int, was offensichtlich erforderlich ist, um das richtige Suffix aus der Tabelle auszuwählen.

Ich empfehle Ihnen, auch einen Unit-Test zu schreiben.

PS Eine ähnliche Formatierer kann auch verwendet werden für das Parsen ein Datum String mit Ordnungszahlen wie 1st, 2ndusw. Das in getan wurde diese Frage: Java - Parse Datum mit optionalen Sekunden .

Link: Oracle-Tutorial: Datum Uhrzeit zur Erläuterung der Verwendung java.time.


Ich würde diese Antwort gerne höher stellen, da diese modernere Antwort besser ist, als zu versuchen, Ihre eigene Implementierung zu rollen.
Krease

9

Wenn Sie versuchen, sich i18n bewusst zu werden, wird die Lösung noch komplizierter.

Das Problem ist, dass in anderen Sprachen das Suffix nicht nur von der Zahl selbst abhängt, sondern auch von dem Substantiv, das es zählt. Zum Beispiel auf 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, eine gute Lösung (ich hatte keine Zeit, sie tatsächlich zu implementieren) wäre, SimpleDateFormetter zu erweitern, um das länderspezifische MessageFormat anzuwenden, bevor es an die übergeordnete Klasse übergeben wird. Auf diese Weise können Sie beispielsweise die März-Formate% M unterstützen, um "3-rd" zu erhalten,% MM, um "03-rd" zu erhalten, und% MMM, um "3" zu erhalten. Von außerhalb sieht diese Klasse wie normaler SimpleDateFormatter aus, unterstützt jedoch mehr Formate. Auch wenn dieses Muster versehentlich vom regulären SimpleDateFormetter angewendet würde, wäre das Ergebnis falsch formatiert, aber dennoch lesbar.


Guter Punkt zu den Geschlechtern auf Russisch, aber das würde% MMM ohne zusätzlichen Kontext technisch unmöglich machen.
Verrückter Physiker

@ Mad Physicist, dies ist nicht wahr, da% MMM auf den Monat angewendet wird, sodass wir das zu konjugierende Substantiv kennen.
CAB

6

Viele der Beispiele hier funktionieren nicht für 11, 12, 13. Dies ist allgemeiner und funktioniert für alle Fälle.

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

5

Ich kann mich nicht mit den Antworten zufrieden geben, die eine Lösung nur für Englisch erfordern, die auf manuellen Formaten basiert. Ich habe jetzt schon eine Weile nach einer richtigen Lösung gesucht und sie endlich gefunden.

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


3

Es gibt einen einfacheren und sichereren Weg, dies zu tun. Die Funktion, die Sie verwenden müssen, ist getDateFromDateString (dateString). Grundsätzlich wird das st / nd / rd / th aus einer Datumszeichenfolge entfernt und einfach analysiert. Sie können Ihr SimpleDateFormat in alles ändern, und dies wird funktionieren.

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;

}}


1
In dieser Antwort geht es darum, einen String zu analysieren, während in der Frage ein String generiert wird . Aber immer noch angemessen, da man wahrscheinlich beide Richtungen braucht. Diese Antwort löst auch diese andere Frage .
Basil Bourque

3

Das einzige Problem mit der von Greg bereitgestellten Lösung ist, dass sie keine Zahl größer als 100 berücksichtigt, wobei 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";
    }
}

6
In welchem ​​Fall hätte eine Tag-Monat-Sequenz mehr als 31 Tage?
SatanEnglish

@SatanEnglish, das Gute an dieser statischen Factory-Methode ist, dass sie nicht nur für das Suffix eines Monats verwendet werden kann. :)
Jared Rummler

1
Diese Methode gibt st für 11, nd für 12 und rd für 13 zurück
TheIT

@ SatanEnglish. Angesichts der Tatsache, dass heute der 137. Februar in meinem Kalender der Wahl ist, denke ich, dass sich Ihre Frage von selbst beantwortet. Im Ernst, nicht-gregorianische Kalender gibt es zuhauf, wenn Sie wissen, wo Sie suchen müssen.
Verrückter Physiker

Nein, @ TheIT, das tut es nicht. Ich habe getestet. Es kehrt thfür 11, 12 und 13 zurück, wie es sollte. Ich glaube, der if ( hunRem - tenRem == 10 )Fall stellt sicher, dass es so ist.
Ole VV

2

RuleBasedNumberFormat in der Intensivbibliothek

Ich habe den Link zur Bibliothek des ICU-Projekts von @ Pierre-Olivier Dybman ( http://www.icu-project.org/apiref/icu4j/com/ibm/icu/text/RuleBasedNumberFormat.html ) sehr geschätzt , musste aber noch herausfinden Informationen zur Verwendung finden Sie weiter RuleBasedNumberFormatunten. Ein Beispiel für die Verwendung finden Sie weiter unten.

Es wird nur eine einzelne Zahl und nicht das gesamte Datum formatiert. Sie müssen also eine kombinierte Zeichenfolge erstellen, wenn Sie nach einem Datum im Format suchen: beispielsweise Montag, 3. Februar.

Der folgende Code legt das RuleBasedNumberFormatFormat als Ordnungszahl für ein bestimmtes Gebietsschema fest, erstellt eine java.time ZonedDateTimeund formatiert die Zahl mit ihrer Ordnungszahl in eine Zeichenfolge.

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

String dayNumAndOrdinal = numOrdinalFormat.format(zdt.toLocalDate().getDayOfMonth());

Beispielausgabe:

3 ..

Oder

4 ..

etc.


1

Hier ist ein Ansatz, der ein DateTimeFormatter-Muster mit dem richtigen Suffix-Literal aktualisiert, wenn es das Muster findet d'00', z. B. für den Tag des Monats 1, durch den es ersetzt wird d'st'. Sobald das Muster aktualisiert wurde, kann es einfach in den DateTimeFormatter eingegeben werden, um den Rest zu erledigen.

private static String[] suffixes = {"th", "st", "nd", "rd"};

private static String updatePatternWithDayOfMonthSuffix(TemporalAccessor temporal, String pattern) {
    String newPattern = pattern;
    // Check for pattern `d'00'`.
    if (pattern.matches(".*[d]'00'.*")) {
        int dayOfMonth = temporal.get(ChronoField.DAY_OF_MONTH);
        int relevantDigits = dayOfMonth < 30 ? dayOfMonth % 20 : dayOfMonth % 30;
        String suffix = suffixes[relevantDigits <= 3 ? relevantDigits : 0];
        newPattern = pattern.replaceAll("[d]'00'", "d'" + suffix + "'");
    }

    return newPattern;
}

Es ist erforderlich, dass das ursprüngliche Muster unmittelbar vor jedem Formatierungsaufruf aktualisiert wird, z

public static String format(TemporalAccessor temporal, String pattern) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(updatePatternWithDayOfMonthSuffix(temporal, pattern));
    return formatter.format(temporal);
}

Dies ist also nützlich, wenn das Formatierungsmuster außerhalb von Java-Code definiert ist, z. B. einer Vorlage, bei der Sie das Muster in Java definieren können und dann die Antwort von @ OleV.V. könnte angemessener sein


1
Kreativ und verschlungen. Ich habe sicherlich lange gebraucht, um zu verstehen, wie es funktioniert. Das ist kein Zeichen für guten Code.
Ole VV

1
@ OleV.V. Danke für das Feedback - Ich habe es ein bisschen umstrukturiert, damit es ein bisschen weniger ausführlich ist. Hab gerade deinen Ansatz gesehen und ich mag es! Ich denke, beide Ansätze sind mit unterschiedlichen Kompromissen gültig. Ihre benötigt zum Zeitpunkt der Formatierung keine weitere Unterstützung, erfordert jedoch, dass das Muster mit dem Builder definiert wird, der die Musterdefinition in Nicht-Java-Code ausschließt. Mein Ansatz erfordert zusätzliche Unterstützung beim Formatieren, aber keine Abhängigkeit vom Builder, um das Muster zu erstellen. Dadurch wird es etwas flexibler, wo das Muster definiert werden kann. Meine Anforderungen diktierten letzteres
Tazmaniax

3
Sehr schöne Darstellung der Vor- und Nachteile. Vielleicht möchten Sie es in die Antwort aufnehmen? Nur eine Idee.
Ole VV

1

Ich habe mir selbst eine Hilfsmethode geschrieben, um Muster dafür zu erhalten.

public static String getPattern(int month) {
    String first = "MMMM dd";
    String last = ", yyyy";
    String pos = (month == 1 || month == 21 || month == 31) ? "'st'" : (month == 2 || month == 22) ? "'nd'" : (month == 3 || month == 23) ? "'rd'" : "'th'";
    return first + pos + last;
}

und dann können wir es als nennen

LocalDate localDate = LocalDate.now();//For reference
int month = localDate.getDayOfMonth();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(getPattern(month));
String date = localDate.format(formatter);
System.out.println(date);

die Ausgabe ist

December 12th, 2018

Dies erfordert jedoch eine Mindest-API von 26 :)
Mikkel Larsen

@MikkelLarsen Bei dieser Frage ging es nicht um Android, ich habe Java 8 dafür verwendet. Android unterstützt keine große API für Java 8.
SamHoque

@ SamSakerz mein schlechtes :)
Mikkel Larsen

@MikkelLarsen Die meisten Funktionen von java.time werden im ThreeTen-Backport- Projekt auf Java 6 und Java 7 zurückportiert . Weiter angepasst für früheres Android (<26) in ThreeTenABP . Siehe Verwendung von ThreeTenABP… .
Basil Bourque

1

Versuchen Sie die folgende Funktion:

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

Wenn Sie eine alte Frage beantworten, ist Ihre Antwort für andere StackOverflow-Benutzer viel nützlicher, wenn Sie einen Kontext angeben, um zu erklären, wie Ihre Antwort hilft, insbesondere für eine Frage, für die bereits eine Antwort akzeptiert wurde. Siehe auch : Wie kann ich eine gute Antwort schreiben .
David Buck

Vielen Dank für Ihren Beitrag. Ich empfehle, dass wir nicht verwenden Date, Calendarund SimpleDateFormat. Diese Klassen sind schlecht gestaltet und längst veraltet, wobei die letzten besonders notorisch problematisch sind. Verwenden Sie stattdessen LocalDateund DateTimeFormattersowohl aus java.time als auch die moderne Java-API für Datum und Uhrzeit . Ich bin auch im Zweifel, was Ihre Antwort im Vergleich zu den anderen 18 Antworten neu beiträgt.
Ole VV

0

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 einstellen

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

-3

Die folgende Methode kann verwendet werden, um die formatierte Zeichenfolge des Datums abzurufen, das an sie übergeben wird. Das Datum wird mit SimpleDateFormat in Java so formatiert, dass es 1., 2., 3., 4. ist. zB: - 1. September 2015

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

-4

Das Folgende ist eine effizientere Antwort auf die Frage, als den Stil fest zu codieren.

Um den Tag in eine Ordnungszahl zu ändern, müssen Sie das folgende Suffix verwenden .

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 dieser Frage.


Die Frage ist, in Java zu formatieren, nicht in der Oracle-Datenbank docs.oracle.com/cd/B12037_01/server.101/b10759/… Java verwendet SimpleDateFormat für das Datum: docs.oracle.com/javase/tutorial/i18n/format/…
Belal Mazlom

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

Es sollte keine EndsWith () verwenden. die falsche Ausgabe produzieren
Rahul Sharma
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.