170

私はこれが私に数字(、、)として月の日を与えることを知ってい11ます:2123

SimpleDateFormat formatDayOfMonth = new SimpleDateFormat("d");

しかし、序数標識、たとえば11th21stまたはを含めるために、どのように月の日をフォーマットしますか23rd

4

23 に答える 23

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

@kaliatech の表は素晴らしいものですが、同じ情報が繰り返されるため、バグが発生する可能性があります。7tnこのようなバグは、 、17tn、およびの表に実際に存在します27tn(このバグは、StackOverflow の流動的な性質のため、時間の経過とともに修正される可能性があるため、回答のバージョン履歴をチェックしてエラーを確認してください)。

于 2010-10-25T00:48:10.227 に答える
57

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

またはカレンダーを使用して:

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

@thorbjørn-ravn-andersen のコメントによると、このような表はローカライズ時に役立ちます。

  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" };
于 2010-10-25T00:09:15.453 に答える
45
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";
    }
}
于 2011-12-12T12:40:45.637 に答える
18
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)];
}
于 2010-10-25T01:26:52.427 に答える
9

i18n を認識しようとすると、解決策はさらに複雑になります。

問題は、他の言語では、接尾辞が数字自体だけでなく、それが数える名詞にも依存する可能性があることです。たとえば、ロシア語では「2-ой день」ですが、「2-ая неделя」になります (これらは「2 日目」を意味しますが、「2 週目」を意味します)。これは、日のみをフォーマットする場合には当てはまりませんが、もう少し一般的なケースでは、複雑さに注意する必要があります。

良い解決策 (実際に実装する時間がありませんでした) は、SimpleDateFormetter を拡張して、親クラスに渡す前に Locale-aware MessageFormat を適用することだと思います。このようにして、3 月のフォーマット %M で「3-rd」を取得し、%MM で「03-rd」を取得し、%MMM で「3 位」を取得することをサポートできます。このクラスの外から見ると、通常の SimpleDateFormatter のように見えますが、より多くの形式をサポートしています。また、このパターンが通常の SimpleDateFormetter によって誤って適用された場合、結果は正しくフォーマットされませんが、それでも読み取り可能です。

于 2014-09-26T17:12:34.600 に答える
5

新しいjava.timeパッケージと新しい Java switch ステートメントを使用すると、次のように簡単に序数を月の日に配置できます。欠点の 1 つは、これがDateFormatterクラスで指定された既定の形式に適していないことです。

何らかの形式で日を作成するだけですが、%s%s後で日と序数を追加するために含めます。

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

ここで、曜日と書式設定されたばかりの日付をヘルパー メソッドに渡して、序数の日を追加します。


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

版画

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

これがヘルパーメソッドです。

Java 14 スイッチ式を使用すると、序数を非常に簡単に取得できます。

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);
}
于 2020-10-06T15:48:28.543 に答える
3

グレッグが提供する解決策の唯一の問題は、「十代」の数字が終わる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";
    }
}
于 2013-02-26T20:26:48.927 に答える
3

これを行うには、より簡単で確実な方法があります。使用する必要がある関数は 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;

}

于 2011-08-08T19:58:13.040 に答える
0

kotlinでは、このように使用できます

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")
于 2018-02-13T07:12:33.960 に答える
-3

次のメソッドを使用して、渡された日付のフォーマットされた文字列を取得できます。JavaでSimpleDateFormatを使用して、日付を1日、2日、3日、4日とフォーマットします。例: - 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);
        }
于 2015-09-02T04:00:08.727 に答える
-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";
  }
}
于 2013-01-14T04:37:58.827 に答える