새 날짜 시간 API를 사용하여 날짜 형식 지정


118

나는 새로운 날짜 시간 API를 가지고 놀았지만 이것을 실행할 때 :

public class Test {         
    public static void main(String[] args){
        String dateFormatted = LocalDate.now()
                                        .format(DateTimeFormatter
                                              .ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.out.println(dateFormatted);
    }
}

던졌습니다 :

Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: HourOfDay
    at java.time.LocalDate.get0(LocalDate.java:680)
    at java.time.LocalDate.getLong(LocalDate.java:659)
    at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
    at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2543)
    at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2182)
    at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1745)
    at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1719)
    at java.time.LocalDate.format(LocalDate.java:1685)
    at Test.main(Test.java:23)

LocalDate 클래스의 소스 코드를 보면 다음과 같습니다.

  private int get0(TemporalField field) {
        switch ((ChronoField) field) {
            case DAY_OF_WEEK: return getDayOfWeek().getValue();
            case ALIGNED_DAY_OF_WEEK_IN_MONTH: return ((day - 1) % 7) + 1;
            case ALIGNED_DAY_OF_WEEK_IN_YEAR: return ((getDayOfYear() - 1) % 7) + 1;
            case DAY_OF_MONTH: return day;
            case DAY_OF_YEAR: return getDayOfYear();
            case EPOCH_DAY: throw new UnsupportedTemporalTypeException("Invalid field 'EpochDay' for get() method, use getLong() instead");
            case ALIGNED_WEEK_OF_MONTH: return ((day - 1) / 7) + 1;
            case ALIGNED_WEEK_OF_YEAR: return ((getDayOfYear() - 1) / 7) + 1;
            case MONTH_OF_YEAR: return month;
            case PROLEPTIC_MONTH: throw new UnsupportedTemporalTypeException("Invalid field 'ProlepticMonth' for get() method, use getLong() instead");
            case YEAR_OF_ERA: return (year >= 1 ? year : 1 - year);
            case YEAR: return year;
            case ERA: return (year >= 1 ? 1 : 0);
        }
        throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
    }

문서에 설명 된대로 :

이 메서드는 클래스 문서에 설명 된대로 문자와 기호의 간단한 패턴을 기반으로 포맷터를 만듭니다.

그리고이 모든 문자가 정의됩니다 .

그렇다면 DateTimeFormatter.ofPattern패턴 문자를 사용하지 않는 이유 는 무엇입니까?

답변:


219

LocalDateDateTime이 아니라 날짜를 나타냅니다. 따라서 "HH : mm : ss"는 LocalDate. LocalDateTime날짜와 시간을 모두 나타내려는 경우 대신 a 를 사용하십시오 .


3
어떻게이 답변을
찬성

저는 LocalTime으로 작업하고 싶습니다.이 예외를 실행하지 않고 포맷을 수행하는 방법java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: DayOfWeek
samuel owino

신경 쓰지 마세요 :이 작품은DateTimeFormatter.ofPattern("HH:mm:ss")
samuel owino

36

@James_D의 정답에 다음 세부 정보를 추가하고 싶습니다.

배경 : 대부분의 날짜 및 시간 라이브러리 ( java.util.CalendarJava에서 .Net-DateTime 또는 DateJavaScript 또는 DateTimePerl 참조)는 범용 다목적 고유 시간 유형의 개념을 기반으로합니다 (독일어에는 시적 표현이 있습니다. " eierlegende Wollmilchsau '). 이 디자인에는 지원되지 않는 필드가있을 수 없습니다. 그러나 가격이 비싸다. 모든 종류의 시간적 객체에 대한 공통 분모를 찾기가 불가능하기 때문에 이러한 융통성없는 접근 방식으로는 문제를 적절히 처리 할 수없는 경우가 많습니다.

JSR-310은 지원되는 내장 필드의 유형별 세트로 구성된 다른 시간 유형을 허용하는 다른 방법을 선택 했습니다. 자연스러운 결과는 모든 가능한 필드가 모든 유형에서 지원되는 것은 아니라는 것입니다 (사용자가 자신 만의 특수 필드를 정의 할 수도 있음). 또한 지원되는 특정 필드 집합에 대해 모든 유형의 개체 를 프로그래밍 방식으로 요청할 수도 있습니다 TemporalAccessor. LocalDate우리는 다음 을 찾습니다.

DAY_OF_WEEK 
ALIGNED_DAY_OF_WEEK_IN_MONTH 
ALIGNED_DAY_OF_WEEK_IN_YEAR 
DAY_OF_MONTH 
DAY_OF_YEAR 
EPOCH_DAY 
ALIGNED_WEEK_OF_MONTH 
ALIGNED_WEEK_OF_YEAR 
MONTH_OF_YEAR 
PROLEPTIC_MONTH 
YEAR_OF_ERA 
YEAR 
ERA 

의 문제를 설명하는 HOUR_OF_DAY 필드가 없습니다 UnsupportedTemporalTypeException. 그리고 JSR-310- 패턴 심볼을 필드 에 매핑하는 것을 보면 심볼 H가 지원되지 않는 HOUR_OF_DAY에 매핑 된 것을 볼 수 있습니다.

/** Map of letters to fields. */  
private static final Map<Character, TemporalField> FIELD_MAP = new HashMap<>();
static {
  FIELD_MAP.put('G', ChronoField.ERA);
  FIELD_MAP.put('y', ChronoField.YEAR_OF_ERA);
  FIELD_MAP.put('u', ChronoField.YEAR);
  FIELD_MAP.put('Q', IsoFields.QUARTER_OF_YEAR);
  FIELD_MAP.put('q', IsoFields.QUARTER_OF_YEAR);
  FIELD_MAP.put('M', ChronoField.MONTH_OF_YEAR);
  FIELD_MAP.put('L', ChronoField.MONTH_OF_YEAR);
  FIELD_MAP.put('D', ChronoField.DAY_OF_YEAR);
  FIELD_MAP.put('d', ChronoField.DAY_OF_MONTH);
  FIELD_MAP.put('F', ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH);
  FIELD_MAP.put('E', ChronoField.DAY_OF_WEEK);
  FIELD_MAP.put('c', ChronoField.DAY_OF_WEEK);
  FIELD_MAP.put('e', ChronoField.DAY_OF_WEEK);
  FIELD_MAP.put('a', ChronoField.AMPM_OF_DAY);
  FIELD_MAP.put('H', ChronoField.HOUR_OF_DAY);
  FIELD_MAP.put('k', ChronoField.CLOCK_HOUR_OF_DAY);
  FIELD_MAP.put('K', ChronoField.HOUR_OF_AMPM);
  FIELD_MAP.put('h', ChronoField.CLOCK_HOUR_OF_AMPM);
  FIELD_MAP.put('m', ChronoField.MINUTE_OF_HOUR);
  FIELD_MAP.put('s', ChronoField.SECOND_OF_MINUTE);
  FIELD_MAP.put('S', ChronoField.NANO_OF_SECOND);
  FIELD_MAP.put('A', ChronoField.MILLI_OF_DAY);
  FIELD_MAP.put('n', ChronoField.NANO_OF_SECOND);
  FIELD_MAP.put('N', ChronoField.NANO_OF_DAY);    
}

이 필드 매핑은 필드가 구체적인 유형에서 지원된다는 것을 의미하지 않습니다. 구문 분석은 여러 단계로 발생합니다. 필드 매핑은 첫 번째 단계 일뿐입니다. 두 번째 단계는 유형의 원시 객체로 구문 분석하는 것 TemporalAccessor입니다. 마지막으로 대리자를 대상 유형 (여기 LocalDate:)으로 구문 분석하고 구문 분석 된 중간 개체의 모든 필드 값을 허용하는지 여부를 결정합니다.


4
en.wiktionary.org/wiki/eierlegende_Wollmilchsau (문자 그대로“계란을 낳는 양모 젖소”) 긍정적 인 속성만을 가지고 있거나 갖고 있다고 주장하는 올인원 장치 또는 사람, 그리고 그럴 수있는 (또는 시도) 몇 가지 특수 도구 작업을 수행합니다. :-)
Trevor Robinson

6

나에게 적합한 수업은 ZonedDateTime시간과 시간대를 모두 포함하는 것이 었습니다 .

LocalDate시간 정보가 없으므로 UnsupportedTemporalTypeException: Unsupported field: HourOfDay.

사용할 수는 LocalDateTime있지만 표준 시간대 정보가 없으므로 미리 정의 된 포맷터 중 하나를 사용하여 액세스하려고하면 UnsupportedTemporalTypeException: Unsupported field: OffsetSeconds.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.