Jak sformatujesz dzień miesiąca, aby powiedzieć „11”, „21” lub „23.” (wskaźnik porządkowy)?

146

Wiem, że to da mi dzień miesiąca jako liczba ( 11, 21, 23):

SimpleDateFormat formatDayOfMonth = new SimpleDateFormat("d");

Ale w jaki sposób formatować dzień miesiąca w celu włączenia porządkowej wskaźnik , powiedzmy 11th, 21stlub 23rd?

Ken Hume
źródło
13
Dla odniesienia są to nazywane liczbami porządkowymi - en.wikipedia.org/wiki/Ordinal_number_(linguistics) .
ocodo
5
Tak dla przypomnienia, wszystko, co tworzy odpowiedź, zamiast przeszukiwać całą odpowiedź w tabeli, jest prawie niemożliwe do zlokalizowania na inne języki.
Thorbjørn Ravn Andersen
2
Odpowiedź jest jakoś niepoprawna, spójrz na moją odpowiedź.
J888,
2
Współczesny komentarz: polecam unikać SimpleDateFormatzajęć. Jest nie tylko dawno przestarzały, ale także notorycznie kłopotliwy. Dziś mamy o wiele lepsze java.time, nowoczesne API daty i czasu Java i jego DateTimeFormatter.
Ole VV
Przyjrzyj się API liczb ( math.tools/api/numbers ). Obsługuje liczbę porządkową, kardynalną, liczbę
zapisaną

Odpowiedzi:

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

Tabela z @kaliatech jest fajna, ale ponieważ ta sama informacja jest powtarzana, otwiera to szansę na błąd. Taki błąd faktycznie istnieje w tabeli dla 7tn, 17tni 27tn(ten błąd może zostać naprawiony w miarę upływu czasu ze względu na płynny charakter StackOverflow, więc sprawdź historię wersji odpowiedzi, aby zobaczyć błąd).

Greg Mattes
źródło
36
to naprawdę wygląda jak przeoczenie w prostym formacie danych, prawda?
stevevls
51
Miłej zabawy w internacjonalizacji tego. : D
Trejkaz
6
@Trejkaz Poza zakresem pytania :)
Greg Mattes
3
To rozwiązanie obsługuje tylko język angielski. Użyj RuleBasedNumberFormat z ICU4J dla zlokalizowanego rozwiązania.
Дмитро Яковлєв
7
Jesteście w chwastach, a ton trochę się zmienia. Nie ma takiej potrzeby. To pytanie nie dotyczyło zawiłości internacjonalizacji. Umiędzynarodowienie jest z pewnością dobrym tematem do omówienia, ale należy zająć się inną kwestią, która dotyczy tego zagadnienia. Zawsze interpretowałem to pytanie jako prośbę o szybki i nieprzyzwoity sposób osiągnięcia tego w języku angielskim. Dlatego proponuję, aby jeśli w świecie Javy naprawdę nie było dobrego rozwiązania, które byłoby przyjazne dla internacjonalizacji, zaczynamy projekt na np. GitHubie i tworzymy dobre rozwiązanie. Daj mi znać, jeśli jesteś zainteresowany.
Greg Mattes
51

W JDK nie ma nic, co mogłoby to zrobić.

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

Lub używając Kalendarza:

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

Zgodnie z komentarzem @ thorbjørn-ravn-andersen, taka tabela może być pomocna podczas lokalizacji:

  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" };
kaliatech
źródło
8
Jeśli pozwolisz, aby tabela zawierała pełne „21.”, „23.”, „29.”, można ją udostępnić na zewnątrz i zlokalizować na inne języki. Skuteczne oprogramowanie, które może stać się wymaganiem.
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";
    }
}
Anand Shekhar
źródło
Właśnie wypróbowałem Twoje rozwiązanie, pomijając pojedyncze cudzysłowy w ciągu znaków dostarczonym do konstruktora SimpleDateFormat. Teraz rozumiem, dlaczego tam są. Otrzymuję z java.lang.IllegalArgumentExceptionpowodu „niedozwolonego wzoru, t”.
typowy Danny
17

Pytanie jest trochę stare. Ponieważ to pytanie jest bardzo głośne, opublikowanie tego, co zrobiłem, rozwiązało przy użyciu metody statycznej jako narzędzia. Po prostu skopiuj, wklej i używaj!

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

Do celów testowych

Przykład: wywołanie go z metody głównej!

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

Wynik:

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
Sarz
źródło
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)];
}
ocodo
źródło
14

Chciałbym przedstawić nowoczesną odpowiedź. SimpleDateFormatKlasy było OK do użycia, gdy pytano 8 lat temu, ale nie należy go teraz, ponieważ nie jest tylko długo nieaktualne, ale także notorycznie kłopotliwe. Użyj java.timezamiast tego.

Edytować

DateTimeFormatterBuilder.appendText(TemporalField, Map<Long, String>)świetnie nadaje się do tego celu. Korzystając z niego, budujemy formater, który wykonuje za nas pracę:

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

Wynik tego fragmentu kodu to:

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

Stara odpowiedź

Ten kod jest krótszy, ale IMHO nie jest tak elegancki.

    // 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()]);

Uruchamiam ten fragment przed chwilą

23

Jedną z wielu cech java.timejest to, że można łatwo i niezawodnie uzyskać dzień miesiąca jako dzień int, co jest oczywiście potrzebne do wybrania odpowiedniego sufiksu z tabeli.

Polecam również napisać test jednostkowy.

PS Podobny formater mogą być również wykorzystywane do analizowania ciąg datę zawierającą numery porządkowe jak 1st, 2ndi inne, które zostało zrobione w tej kwestii: Java - datę Parse z opcjonalnymi sekund .

Link: samouczek Oracle: Date Time wyjaśniający, jak używać java.time.

Ole VV
źródło
Chciałbym, aby ta odpowiedź była wyższa, ponieważ ta bardziej nowoczesna odpowiedź jest lepsza niż próba wprowadzenia własnej implementacji.
Krease
9

Jeśli spróbujesz być świadomy i18n, rozwiązanie staje się jeszcze bardziej skomplikowane.

Problem w tym, że w innych językach przyrostek może zależeć nie tylko od samej liczby, ale także od rzeczownika, który się liczy. Na przykład w języku rosyjskim będzie to „2-ой день”, ale „2-ая неделя” (to znaczy „2. dzień”, ale „2. tydzień”). Nie ma to zastosowania, jeśli formatujemy tylko dni, ale w nieco bardziej ogólnym przypadku powinieneś być świadomy złożoności.

Myślę, że fajnym rozwiązaniem (nie miałem czasu na implementację) byłoby rozszerzenie SimpleDateFormetter, aby zastosować MessageFormat obsługujący locale przed przejściem do klasy nadrzędnej. W ten sposób możesz obsługiwać, powiedzmy, formaty% M w marcu, aby uzyskać „3-rd”,% MM, aby uzyskać „03-rd”, a% MMM, aby uzyskać „trzeci”. Z zewnątrz ta klasa wygląda jak zwykła SimpleDateFormatter, ale obsługuje więcej formatów. Również jeśli ten wzorzec zostałby przez pomyłkę zastosowany przez zwykłe SimpleDateFormetter, wynik byłby nieprawidłowo sformatowany, ale nadal czytelny.

TAKSÓWKA
źródło
Słuszna uwaga na temat płci w języku rosyjskim, ale technicznie uniemożliwiłoby to% MMM bez dodatkowego kontekstu.
Mad Physicist
@Mad Physicist, to nie jest prawda, ponieważ% MMM zostanie zastosowane do miesiąca, więc znamy rzeczownik do koniugacji.
CAB
6

Wiele z przedstawionych tutaj przykładów nie będzie działać dla 11, 12, 13. Jest to bardziej ogólne i będzie działać we wszystkich przypadkach.

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";
}
sivag1
źródło
5

Nie mogę być usatysfakcjonowany odpowiedziami wzywającymi do rozwiązania w języku angielskim opartego na ręcznych formatach. Od jakiegoś czasu szukałem odpowiedniego rozwiązania i w końcu go znalazłem.

Powinieneś używać RuleBasedNumberFormat . Działa doskonale i szanuje lokalizację.

Pierre-Olivier Dybman
źródło
3

Jest na to prostszy i pewniejszy sposób. Funkcja, której będziesz potrzebować, to getDateFromDateString (dateString); Zasadniczo usuwa st / nd / rd / th z łańcucha daty i po prostu go analizuje. Możesz zmienić SimpleDateFormat na cokolwiek i to zadziała.

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;

}

Erdem Memisyazici
źródło
1
Ta odpowiedź dotyczy analizowania ciągu, podczas gdy pytanie dotyczy generowania ciągu. Ale nadal odpowiednie, ponieważ prawdopodobnie potrzebujesz obu kierunków. Ta odpowiedź rozwiązuje również to drugie pytanie .
Basil Bourque
3

Jedynym problemem z rozwiązaniem dostarczonym przez Grega jest to, że nie uwzględnia liczby większej niż 100 z końcówką „nastolatka”. Na przykład 111 powinno być 111, a nie 111. To jest moje rozwiązanie:

/**
 * 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";
    }
}
Talisfera
źródło
6
W jakim przypadku sekwencja dnia i miesiąca miałaby więcej niż 31 dni?
SatanEnglish
@SatanEnglish, dobrą rzeczą w tej statycznej metodzie fabrycznej jest to, że można jej używać nie tylko do uzyskiwania sufiksu miesiąca. :)
Jared Rummler
1
Ta metoda zwraca st dla 11, nd dla 12 i rd dla 13
TheIT
@SatanEnglish. Biorąc pod uwagę, że dzisiaj jest 137 lutego w moim wybranym kalendarzu, myślę, że twoje pytanie samo odpowiada. Poważnie, kalendarze inne niż gregoriańskie są pełne, jeśli wiesz, gdzie szukać.
Mad Physicist
Nie, @ TheIT, tak nie jest. Testowałem. Wraca thpo 11, 12 i 13 tak, jak powinien. Uważam, że if ( hunRem - tenRem == 10 )sprawa zapewnia to.
Ole VV
2

RuleBasedNumberFormat w bibliotece ICU

Doceniam link do biblioteki projektu ICU z @ Pierre-Olivier Dybman ( http://www.icu-project.org/apiref/icu4j/com/ibm/icu/text/RuleBasedNumberFormat.html ), jednak nadal musiałem się zastanowić jak go używać, przykład RuleBasedNumberFormatużycia jest poniżej.

Formatuje tylko pojedynczą liczbę, a nie całą datę, więc jeśli szukasz daty w formacie: na przykład poniedziałek 3 lutego, musisz utworzyć połączony ciąg.

Poniższy kod ustawia RuleBasedNumberFormatformat porządkowy jako porządkowy dla danego ustawienia regionalnego, tworzy a java.time ZonedDateTime, a następnie formatuje liczbę wraz z jej liczbą porządkową w ciągu.

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

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

Przykładowe dane wyjściowe:

3

Lub

4

itp.

tbigby
źródło
1

Oto podejście, które aktualizuje wzorzec DateTimeFormatter poprawnym literałem sufiksu, jeśli znajdzie wzorzec d'00', np. Dla dnia miesiąca 1 zostanie zastąpiony przez d'st'. Po zaktualizowaniu wzorca można go po prostu wprowadzić do DateTimeFormatter, aby wykonać resztę.

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

Wymaga to aktualizacji oryginalnego wzorca tuż przed każdym wywołaniem formatowania, np

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

Jest to więc przydatne, jeśli wzorzec formatowania jest zdefiniowany poza kodem Java, np. Szablonem, gdzie jakbyś mógł zdefiniować wzorzec w Javie, a następnie odpowiedź przez @ OleV.V. może być bardziej odpowiednie

tazmaniax
źródło
1
Kreatywny i zawiły. Z pewnością zajęło mi dużo czasu, zanim zrozumiałem, jak to działa. To nie jest oznaka dobrego kodu.
Ole VV
1
@ OleV.V. dzięki za informacje zwrotne - trochę go przebudowałem, więc jest trochę mniej szczegółowy. Właśnie widziałem twoje podejście i podoba mi się! Myślę, że oba podejścia są ważne z różnymi kompromisami. Twój nie wymaga dalszej obsługi w momencie formatowania, ale wymaga, aby wzorzec był zdefiniowany za pomocą konstruktora, który wyklucza definicję wzorca w kodzie innym niż Java. Moje podejście wymaga dodatkowego wsparcia w momencie formatowania, ale nie jest zależne od konstruktora przy tworzeniu wzorca, więc sprawia, że ​​jest nieco bardziej elastyczny, gdy można zdefiniować wzorzec. Moje wymagania podyktowały to drugie
tazmaniax
3
Bardzo fajne zestawienie zalet i wad. Możesz zawrzeć to w odpowiedzi? Tylko pomysł.
Ole VV
1

Napisałem własną metodę pomocniczą, aby uzyskać wzorce do tego.

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

a potem możemy nazwać to jako

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

wyjście jest

December 12th, 2018
SamHoque
źródło
Wymaga to jednak minimum 26 API :)
Mikkel Larsen,
@MikkelLarsen to pytanie nie dotyczyło Androida, używałem do tego Javy 8. Android nie obsługuje dużego interfejsu API dla java 8.
SamHoque
@SamSakerz my bad :)
Mikkel Larsen
@MikkelLarsen Większość funkcji java.time jest przenoszona z powrotem do Java 6 i Java 7 w projekcie ThreeTen-Backport . Dalsze dostosowanie do wcześniejszego Androida (<26) w ThreeTenABP . Zobacz Jak używać ThreeTenABP… .
Basil Bourque
1

Wypróbuj poniższą funkcję:

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);
}
MEGHA DOBARIYA
źródło
Odpowiadając na stare pytanie, twoja odpowiedź byłaby znacznie bardziej przydatna dla innych użytkowników StackOverflow, gdybyś zawarł kontekst wyjaśniający, w jaki sposób twoja odpowiedź pomaga, szczególnie w przypadku pytania, na które już została zaakceptowana odpowiedź. Zobacz: Jak napisać dobrą odpowiedź .
David Buck
Dzięki za chęć udziału. Polecam nie używamy Date, Calendara SimpleDateFormat. Zajęcia te są źle zaprojektowane i dawno przestarzałe, a te ostatnie są szczególnie kłopotliwe. Zamiast tego użyj LocalDatei DateTimeFormatter, zarówno z java.time, nowoczesnego interfejsu API daty i czasu Java . Nie mam też wątpliwości, co nowego wnosi Twoja odpowiedź w porównaniu z pozostałymi 18 odpowiedziami?
Ole VV
0

W kotlinie możesz używać w ten sposób

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

ustawić w ten sposób

  txt_chat_time_me.text = changeDateFormats("SERVER_DATE", "DATE")
Mohit Suthar
źródło
-3

Poniższa metoda może służyć do pobrania sformatowanego ciągu z datą, która jest do niego przekazywana. Data zostanie sformatowana jako pierwsza, druga, trzecia, czwarta ... przy użyciu SimpleDateFormat w Javie. np .: - 1 września 2015 r

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);
        }
Nadeeshani
źródło
-4

Poniższa odpowiedź jest bardziej skuteczną odpowiedzią na pytanie niż zapisywanie stylu na stałe.

Aby zmienić dzień na liczbę porządkową, musisz użyć następującego przyrostka .

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

OR to spell the number add SP to the format

DD + SPTH = DDSPTH   result >>> FOURTH

Znajdź moją pełną odpowiedź na to pytanie.

J888
źródło
Pytanie dotyczy formatowania w Javie, a nie w bazie danych Oracle docs.oracle.com/cd/B12037_01/server.101/b10759/ ... Java używa SimpleDateFormat dla daty: 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";
  }
}
Simeon Hearring
źródło
Nie powinno używać endWith (); które dają złe wyniki
Rahul Sharma