새 날짜 시간 API를 사용하여 날짜 형식 지정
나는 새로운 날짜 시간 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
패턴 문자를 사용하지 않는 이유 는 무엇입니까?
LocalDate
DateTime이 아니라 날짜를 나타냅니다. 따라서 "HH : mm : ss"는 LocalDate
. LocalDateTime
날짜와 시간을 모두 나타내려는 경우 대신 a 를 사용하십시오 .
@James_D의 정답에 다음 세부 정보를 추가하고 싶습니다.
Background: Most date-and-time-libraries (java.util.Calendar
in Java, see also .Net-DateTime or Date
in JavaScript or DateTime
in Perl) are based on the concept of a universal all-purpose unique temporal type (in German there is the poetic expression "eierlegende Wollmilchsau"). In this design there cannot be an unsupported field. But the price is high: Many time problems cannot be adequately handled with such an unflexible approach because it is hard to impossible to find a common denominator for all kinds of temporal objects.
JSR-310 has choosen another way, namely to allow different temporal types which consist of type-specific sets of supported built-in fields. The natural consequence is that not every possible field is supported by every type (and users can even define their own specialized fields). It is also possible to programmatically ask every object of type TemporalAccessor
for its specific set of supported fields. For LocalDate
we find:
•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
There is no HOUR_OF_DAY-field which explains the problem of UnsupportedTemporalTypeException
. And if we look at the JSR-310-mapping of pattern symbols to fields we see that the symbol H is mapped to unsupported 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);
}
This field mapping does not mean that the field is supported by the concrete type. Parsing happens in several steps. The field mapping is only the first step. The second step is then parsing to a raw object of type TemporalAccessor
. And finally parsing delegates to the target type (here: LocalDate
) and let it decide if it accepts all the field values in parsed intermediate object.
The right class for me was ZonedDateTime
which includes both Time and Time Zone.
LocalDate
doesn't have the Time information so you get a UnsupportedTemporalTypeException: Unsupported field: HourOfDay
.
You can use LocalDateTime
but then you don't have the Time Zone information so if you try to access that (even by using one of the predefined formatters) you will get a UnsupportedTemporalTypeException: Unsupported field: OffsetSeconds
.
참고URL : https://stackoverflow.com/questions/23069370/format-a-date-using-the-new-date-time-api
'program story' 카테고리의 다른 글
Android Marshmallow의 서비스에서 권한을 요청하는 방법 (0) | 2020.08.24 |
---|---|
RESTful API의 API 키 vs HTTP 인증 vs OAuth (0) | 2020.08.24 |
UIImage에서 기본 NSData 가져 오기 (0) | 2020.08.23 |
forEach는 JavaScript 배열의 함수 오류가 아닙니다. (0) | 2020.08.23 |
특정 문자열로 시작하는 모든 클래스 제거 (0) | 2020.08.23 |