문제

날짜를 나타내는 문자열이 있습니다 프랑스 국민 로케일 : 09-OCT-08 :

필요합니다 구문 분석 그 끈이기 때문에이 단순한 형태를 생각해 냈습니다.

String format2 = "dd-MMM-yy";

그러나 나는 달 부분에 문제가 있는데, 그것은 결말로 예상되는 것 같습니다.

df2.format(new Date());

나에게 제공 :

 28-oct.-09

SimpledateFormat을 이해하게하는 가장 좋은 방법은 무엇입니까 ( "09-OCT-08")?

전체 코드 :

String format2 = "dd-MMM-yy"; 
DateFormat df2 = new SimpleDateFormat(format2,Locale.FRENCH); 
date = df2.parse("09-oct-08"); 

이것은 나에게 제공합니다 : java.text.parseexception : 숭배 할 수없는 날짜 : "09-OCT-08"

그리고 내가 로그인하면 :

df2.format(new Date()); 

나는 얻을 것이다 : 28-oct.-09

도움이 되었습니까?

해결책

이것은 작동하는 것 같습니다 :

    DateFormatSymbols dfsFr = new DateFormatSymbols(Locale.FRENCH);
    String[] oldMonths = dfsFr.getShortMonths();
    String[] newMonths = new String[oldMonths.length];
    for (int i = 0, len = oldMonths.length; i < len; ++ i) {
        String oldMonth = oldMonths[i];

        if (oldMonth.endsWith(".")) {
            newMonths[i] = oldMonth.substring(0, oldMonths[i].length() - 1);
        } else {
            newMonths[i] = oldMonth;
        }
    }
    dfsFr.setShortMonths(newMonths);
    DateFormat dfFr = new SimpleDateFormat(
        "dd-MMM-yy", dfsFr);

    // English date parser for creating some test data.
    DateFormat dfEn = new SimpleDateFormat(
        "dd-MMM-yy", Locale.ENGLISH);
    System.out.println(dfFr.format(dfEn.parse("10-Oct-09")));
    System.out.println(dfFr.format(dfEn.parse("10-May-09")));
    System.out.println(dfFr.format(dfEn.parse("10-Feb-09")));

편집 : St. Shadow가 나를 이길 것 같습니다.

다른 팁

""를 간단히 제거 할 수 있습니다. :

df2.format(new Date()).replaceAll("\\.", ""));

편집, 레몬 대답:

로케일 프랑스어를 사용할 때 서식에 문제가있는 것 같습니다. 따라서 나는 당신이 단순히 사용하는 것이 좋습니다 . 내가 설명한대로 제거.

실제로 다음 코드 :

    String format2 = "dd-MMM-yy";
    Date date = Calendar.getInstance().getTime();
    SimpleDateFormat sdf = new SimpleDateFormat(format2, Locale.FRENCH);
    System.out.println(sdf.format(date));
    sdf = new SimpleDateFormat(format2, Locale.ENGLISH);
    System.out.println(sdf.format(date));

다음 출력을 표시합니다.

28-oct.-09
28-Oct-09

다시 편집하십시오

좋아, 지금 당신의 문제가 발생했습니다.

먼저 문자열을 처리하지 않고이 문제를 어떻게 해결할 수 있는지 잘 모르겠습니다. 아이디어는 원래 문자열의 달을 포괄적 인 달로 바꾸는 것입니다.

        String[] givenMonths = { "jan", "fév", "mars", "avr.", "mai", "juin", "juil", "août", "sept", "oct", "nov", "déc" };
        String[] realMonths = { "janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc." };
        String original = "09-oct-08";
        for (int i = 0; i < givenMonths.length; i++) {
            original = original.replaceAll(givenMonths[i], realMonths[i]);
        }
        String format2 = "dd-MMM-yy";
        DateFormat df2 = new SimpleDateFormat(format2, Locale.FRENCH);
        Date date = df2.parse(original);
        System.out.println("--> " + date);

동의합니다. 이것은 끔찍하지만 다른 솔루션이 보이지 않습니다. SimpleDateFormat 그리고 Date 클래스.

또 다른 해결책은 a를 사용하는 것입니다 진짜 다음과 같은 원래 JDK 대신 날짜 및 시간 라이브러리 조다 시간.

String format2 = "dd-MMM-yy";
Date date = Calendar.getInstance().getTime();
SimpleDateFormat sdf = new SimpleDateFormat(format2);
System.out.println(sdf.format(date));

출력 28-Oct-09

나는 어떤 점이 보이지 않습니다. 인쇄물을 다시 확인해 보셨습니까? 어쩌면 당신은 실수로 a . 당신 옆 MMM?


당신은 얻고 있습니다 java.text.ParseException: Unparseable date: "09-oct-08" ~부터 "09-oct-08" 형식과 일치하지 않습니다 Locale.FRENCH 기본 로케일 (우리 생각)을 사용하거나 추가 . 당신 옆 oct

좋아, 그런 다음«Brute Force»:)

DateFormatSymbols dfs = new DateFormatSymbols(Locale.FRENCH);
String[] months = new String[13]
<fill with correct month names or just replace these month, that are not fully correct>
dfs.setMonths(months);
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yy", dfs);
Date nweDate = sdf.parse("09-fév-08");

Java.Time

인지 봅시다 Java.Time 프레임 워크가 도움이 될 수 있습니다.

Java.Time에 대해

그만큼 Java.Time Java 8에 내장 된 프레임 워크는 귀찮은 오래된 java.util.date/.calendar 클래스를 대체합니다. 새로운 수업은 매우 성공적인 수업에서 영감을 얻었습니다 조다-시간 후임자로 의도 된 프레임 워크, 개념은 비슷하지만 재건 된 프레임 워크. 정의 JSR 310. 연장 Threeten-extra 프로젝트. 참조 지도 시간.

LocalDate

이전 클래스와 달리 Java.Time은 다음을 제공합니다 LocalDate 클래스는 시간 전용 값을 나타내며 시간 구역이없는 시간 또는 시간대가 없습니다.

프랑스 약어

Java.Time의 Formatters가 약식 월 이름을 기대하는 것을 살펴보십시오. en français.

우리는 반복 할 수 있습니다 Month 개월 목록을 얻기위한 열거. 이 열거는 getDisplayName 이달의 현지화 된 이름을 생성하는 방법. 이 코드는이 방법이 Java.Time Formatter와 동일한 출력을 생성 함을 보여줍니다.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "dd-MMM-yyyy" ).withLocale ( Locale.FRENCH );
for ( Month month : Month.values () ) {
    LocalDate localDate = LocalDate.of ( 2015 , month.getValue () , 1 );
    String output = formatter.format ( localDate );
    String displayName = month.getDisplayName ( TextStyle.SHORT , Locale.FRENCH );
    System.out.println ( "output: " + output + " | displayName: " + displayName );// System.out.println ( "input: " + input + " → " + localDate + " → " + output );
}
output: 01-janv.-2015 | displayName: janv.
output: 01-févr.-2015 | displayName: févr.
output: 01-mars-2015 | displayName: mars
output: 01-avr.-2015 | displayName: avr.
output: 01-mai-2015 | displayName: mai
output: 01-juin-2015 | displayName: juin
output: 01-juil.-2015 | displayName: juil.
output: 01-août-2015 | displayName: août
output: 01-sept.-2015 | displayName: sept.
output: 01-oct.-2015 | displayName: oct.
output: 01-nov.-2015 | displayName: nov.
output: 01-déc.-2015 | displayName: déc.

우리는 3과 4 문자 철자가 혼합되어 있습니다. 더 긴 이름은 4 자와 기간으로 약칭됩니다 (마침표). 4 개월은 약어없이 사용할 수있을 정도로 짧은 이름을 가지고 있습니다. mars, mai, juin, août.

따라서 다른 답변에서 논의 된 바와 같이 간단한 해결책은 없습니다.

데이터 소스를 수정하십시오

첫 번째 제안은 데이터 소스를 수정하는 것입니다. 그 출처는 약어에 대한 적절한 프랑스 규칙을 따르지 않는 것 같습니다. 예일 대학 Java 8의 프랑스어에 대한 이해에 동의합니다. 그건 그렇고, 데이터 소스를 수정하면 4 자리를 두 번째로 사용하면 혼란과 모호성이 끝나지 않습니다.

입력을 수정하십시오

물론 소스는 귀하의 통제/영향을받지 못할 수 있습니다. 이 경우 다른 답변과 마찬가지로, 당신은 상자를 대체해야 할 수도 있습니다. 반면에 입력의 유일한 문제가 단순히 기간 (전체 정지)이 누락되면 Month 부적절한 값을 하드 코딩하기보다는 열거입니다.

나는 초기 구문 분석을 시도 할 것이다. TRAP DateTimeParseException, 수정을 시도하기 전에. 예외가 발생하면 입력을 수정하십시오.

입력을 고정하려면 가능한 열거 인스턴스 세트를 반복하여 연중 매달 시도하십시오. 매달 약식 이름을 얻으십시오. 우리가 의심하는 것과 일치하도록 약어에서 기간 (전체 정지)을 제거하십시오. 그것이 실제로 입력과 일치하는지 확인하십시오. 그렇지 않다면 다음 달에 가십시오.

우리가 일치 할 때, 입력을 수정하여 로케일의 규칙에 대해 적절하게 약식 될 수 있습니다 (우리의 경우 프랑스 규칙). 그런 다음 고정 입력을 구문 분석하십시오. 우리가 초기 시도를했기 때문에 이것은 우리의 두 번째 구문 분석 시도 일 것입니다. 이 두 번째 시도가 실패하면 FIXME: 여기서 보았습니다. 그러나 일반적 으로이 두 번째 구문 분석 시도는 성공할 것이며 우리는 for 루프 Month 열거적.

마지막으로, 결과가 여전히 처음에 설정된 가짜 플래그 값인지 테스트하여 성공을 확인할 수 있습니다 (LocalDate.MIN).

String input = "09-oct-08"; // Last two digits are Year.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "dd-MMM-yy" ).withLocale ( Locale.FRENCH );
LocalDate localDate = LocalDate.MIN; // Some folks prefer a bogus default value as a success/failure flag rather than using a NULL.
try {
    localDate = LocalDate.parse ( input , formatter );
} catch ( DateTimeParseException e ) {
    // Look for any month name abbreviation improperly missing the period (FULL STOP).
    for ( Month month : Month.values () ) {
        String abbreviation = month.getDisplayName ( TextStyle.SHORT , Locale.FRENCH );
        String abbreviationWithoutFullStop = abbreviation.replace ( "." , "" ); // Get short abbreviation, but drop any period (FULL STOP).
        String proper = "-" + abbreviation + "-";
        String improper = "-" + abbreviationWithoutFullStop + "-";
        if ( input.contains ( improper ) ) {
            String inputFixed = input.replace ( improper , proper );
            try {
                localDate = LocalDate.parse ( inputFixed , formatter );
            } catch ( DateTimeParseException e2 ) {
                // FIXME: Handle this error. We expected this second parse attempt to succeed.
            }
            break; // Bail-out of the loop as we got a hit, matching input with a particular improper value.
        }
    }
}
Boolean success =  ! ( localDate.equals ( LocalDate.MIN ) );
String formatted = formatter.format ( localDate );;
String outputImproper = formatted.replace ( "." , "" );  // Drop any period (FULL STOP).

콘솔에 덤프.

System.out.println ( "success: " + success + ". input: " + input + " → localDate: " + localDate + " → formatted: " + formatted + " → outputImproper: " + outputImproper );

성공 : 사실. 입력 : 09-OCT-08 → LocalDate : 2008-10-09 → 형식 : 09-OCT.-08 → OutputImProper : 09-OCT-08

나는 같은 문제 (프랑스어와 여분의 점)를 가지고 있었고이 문제를 해결하는 올바른 방법은 프랑스 지역을 전 세계적으로 덮어 쓰는 것입니다.

import moment from 'moment';
moment.locale('fr', { monthsShort: 'janv_févr_mars_avr_mai_juin_juil_août_sept_oct_nov_déc'.split('_') });

원래 monthsShort 프랑스 물체에는 점이 있습니다janv._févr._mars_avr._..., 우리는 단지 그들을 제거하고 있습니다.

여기에 있습니다 문서에 링크 덮어 쓸 수있는 것을 확인할 수있는 곳.

IE를 덮어 쓰고 싶다면 완전한 로케일 객체를 통과 할 필요가 없습니다. monthsShort.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top