[java] 달의 형식을 “11 일”, “21 일”또는 “23 일”(표준 표시기)로 어떻게 지정합니까?

나는이 숫자로 나에게 그 달의 날짜를 줄 것이다 알고있다 ( 11, 21, 23) :

SimpleDateFormat formatDayOfMonth = new SimpleDateFormat("d");

하지만 어떻게 당신은 포함 할 달의 날짜를 포맷 할 순서 표시 , 말 11th, 21st또는 23rd?



답변

// 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의 유체 성격에 간다이 버그가 수정 얻을 수있는 대답의 버전 기록을 오류를보고).


답변

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


답변

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


답변

질문이 조금 낡았습니다. 이 질문은 시끄럽기 때문에 정적 방법으로 해결 한 것을 util로 게시하는 것이 좋습니다. 복사하여 붙여 넣기 만하면됩니다!

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

자당 테스트

예 : main 메소드에서 호출하십시오!

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

산출:

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


답변

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


답변

나는 현대의 답변에 기여하고 싶습니다. 이 SimpleDateFormat질문은 8 년 전에 질문을 받았을 때 사용하기에 좋았지 만 오래 걸리는 것뿐만 아니라 악명 높은 문제이므로 지금은 피해야합니다. java.time대신 사용하십시오 .

편집하다

DateTimeFormatterBuilder.appendText(TemporalField, Map<Long, String>)이 목적에 좋습니다. 그것을 사용하여 우리를 위해 일하는 포맷터를 만듭니다.

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

이 스 니펫의 출력은 다음과 같습니다.

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

이전 답변

이 코드는 짧지 만 IMHO는 그렇게 우아하지 않습니다.

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

방금이 스 니펫을 실행하면

23 일

의 많은 기능 중 하나는 java.time월의 일을으로 얻는 것이 간단하고 신뢰할 수 있다는 것 int입니다. 이는 테이블에서 올바른 접미사를 선택하는 데 분명히 필요합니다.

단위 테스트도 작성하는 것이 좋습니다.

PS 유사한 포맷도 사용할 수 있습니다 구문 분석 유사한 서수를 포함하는 날짜 문자열 1st, 2nd이루어졌다 등 :이 질문에 선택적 초와 구문 분석 일 – 자바를 .

링크 : 오라클 튜토리얼 : 날짜 시간 사용하는 방법을 설명 java.time.


답변

i18n을 알고 자하면 솔루션이 더욱 복잡해집니다.

문제는 다른 언어에서 접미사가 숫자 자체뿐만 아니라 계산되는 명사에도 의존 할 수 있다는 것입니다. 예를 들어 러시아어에서는 “2-ой день”이지만 “2-ая неделя”( “2 일째”, “2 주차”)입니다. 며칠 만 서식을 지정하는 경우에는 적용되지 않지만 좀 더 일반적인 경우에는 복잡성을 알고 있어야합니다.

좋은 해결책 (실제로 구현 할 시간이 없었습니다)은 부모 클래스에 전달하기 전에 SimpleDateFormetter를 확장하여 로케일 인식 MessageFormat을 적용하는 것입니다. 이렇게하면 3 월 형식 % M에서 “3rd”를, % MM에서 “03-rd”를, % MMM에서 “third”를 얻을 수 있습니다. 이 클래스 외부에서 일반 SimpleDateFormatter처럼 보이지만 더 많은 형식을 지원합니다. 또한이 패턴이 일반 SimpleDateFormetter에 의해 실수로 적용된 경우 결과의 형식이 잘못되었지만 여전히 읽을 수 있습니다.