2017-03-23 1 views
2

다음 형식을 사용하여 날짜를 구문 분석해야합니다. "201710"여기서 10 - 주 번호.LocalDate가 'yyyy'와 (과) 'ww'을 구문 분석 할 수 없습니다.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyw"); 
java.time.LocalDate startDate = java.time.LocalDate.parse("201710", formatter); 
System.out.println(startDate); 

을하지만 예외가 발생합니다 : :이 방법으로 그것을 구현하기 위해 노력

java.time.format.DateTimeParseException: Text '201710' could not be parsed at index 0 

그리고 그 후 나는 LOCALDATE 개체에서 일주일의 첫 번째와 마지막 일을 얻을 필요가있다. 예 : '201710'- 05.03 12.03 (주중 첫 번째 요일은 일요일이어야 함)

+1

코드와 예외가 일치하지 않아야합니다. 코드는 "201710"이라고하지만 예외는 "2017101"이라고합니다. 아마 오타일까요? –

+0

단지 오타입니다. 예외는 java.time.format.DateTimeParseException : '201710'텍스트를 인덱스 0에서 파싱 할 수 없습니다. "yyyyw"형식을 지원하지 않습니다. 문제가 무엇입니까? –

+1

새로운'java.time' 클래스는 이전 클래스처럼 사용자 친화적 인 것처럼 보입니다. – Kayaman

답변

2

표준 날짜 표현 (yyyy = 시대의 연대 사용)과 주간 날짜 표현 (ww = 주 기준 연도 사용)을 혼합 할 수 없기 때문에 @Kayaman의 대답은 정확하지 않습니다. 표준 연도와 주 단위 연도의 하위 구분 차이는 해당 연도의 시작 또는 끝 부분과 관련이 있습니다. 결론 : 기호 "y"가 아니라 기호 "Y"를 사용하십시오. 입력 "201501"에 대한 카운터 예 :

올바른 솔루션 @Kayaman의 제안을 바탕으로

DateTimeFormatter formatter = 
    new DateTimeFormatterBuilder() 
    .appendValue(WeekFields.ISO.weekBasedYear(), 4) 
    .appendValue(WeekFields.ISO.weekOfWeekBasedYear(), 2) 
    .parseDefaulting(ChronoField.DAY_OF_WEEK, 1) 
    .toFormatter(); 
LocalDate startDate = LocalDate.parse("201501", formatter); 
System.out.println(startDate); // 2014-12-29 

:

DateTimeFormatter dtf = 
    new DateTimeFormatterBuilder() 
    .appendValue(ChronoField.YEAR, 4) 
    .appendValue(ChronoField.ALIGNED_WEEK_OF_YEAR, 2) 
    .parseDefaulting(WeekFields.ISO.dayOfWeek(), 1) 
    .toFormatter(); 
System.out.println(LocalDate.parse("201501", dtf)); // 2015-01-05 (wrong) 

결과 날짜가 다르다! 그 차이는 항상 1 월 1 일에 시작하는 달력 연도의 정의로 인해 발생하며, 1 주 단위의 연도는 항상 최소한 4 일이되는 달력 연도의 첫 번째 주를 사용하는 월요일 (ISO-8601 정의)에서 시작됩니다.

추가 노트가) : 자바-8 주 기반의 필드와 같은 localizible 필드의 인접한 자리 구문 분석 (도 관련 JDK issue 참조를 관리하지 않습니다)는, 그러므로 나는를 정의하는 대신 빌더 기반 솔루션을 선택했습니다 패턴 "YYYYww"(그러나 Java-9는 해결책을 약속합니다). 그러나 Java-9를 사용하더라도 누락 된 요일에 대한 기본값을 정의해야하므로 빌드 기반 방식이 여전히 필요합니다 (여기에서는 월요일로 설정).

추가 주 2) : 당신이 일주일에 기반 해 바로이 누락 된 유형에 대한 해결 방법으로 LocalDate를 사용하여 일주일에 세와의 조합에 대해 트루 타입을 찾는 경우에, 잘, 당신은 찾을 수 있습니다 Threeten-Extra 또는 내 라이브러리 Time4J에있는 타사 라이브러리에서 이러한 유형. 예 :

ChronoFormatter<CalendarWeek> cf = 
     ChronoFormatter.ofPattern(
      "YYYYww", 
      PatternType.CLDR, 
      Locale.ROOT, 
      CalendarWeek.chronology() 
     ); 
    CalendarWeek cw = cf.parse("201501"); 
    System.out.println(cw); // 2015-W01 
    System.out.println(cw.at(Weekday.MONDAY)); // 2014-12-29 
2

(이전) duplicate은 값 사이에 공백이 있으면 작동하지만 다음 공백없이 다음 구문을 잘 해석합니다. SUNDAY_STARTISO로 교체

DateTimeFormatter dtf = new DateTimeFormatterBuilder() 
     .appendValue(ChronoField.YEAR, 4) 
     .appendValue(ChronoField.ALIGNED_WEEK_OF_YEAR, 2) 
     .parseDefaulting(WeekFields.SUNDAY_START.dayOfWeek(), 1) 
     .toFormatter(); 

System.out.println(LocalDate.parse("201710", dtf)); 
// 2017-03-05 

당신에게 월요일 (그래서 2017-03-06를 출력한다)로 시작하는 주를 줄 것이다.

+0

@ 그레이엄 (Wille Graham), 일년 내내 정렬 된 주를 원하면 확인하십시오. 일관되고 특이합니다. 주별 연도 및 주 번호를 원할 수 있습니다. 그것은 당신이 필요에 맞게 조정할 수있는 작업 코드를 제공한다는 점에서 좋은 대답입니다. –

+0

나는 내 대답에 반례를 주었다. –

관련 문제