[java] 인스턴트를 문자열로 형식화

새로운 java 8 time-api와 패턴을 사용하여 Instant to String을 형식화하려고합니다.

Instant instant = ...;
String out = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(instant);

위의 코드를 사용하면 지원되지 않는 필드를 불평하는 예외가 발생합니다.

java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: YearOfEra
    at java.time.Instant.getLong(Instant.java:608)
    at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
    ...



답변

시간대

포맷하려면 Instant시간대가 필요합니다. 시간대가 없으면 포맷터는 순간을 인간 날짜-시간 필드로 변환하는 방법을 모르므로 예외가 발생합니다.

시간대를 사용하여 포맷터에 직접 추가 할 수 있습니다 withZone().

DateTimeFormatter formatter =
    DateTimeFormatter.ofLocalizedDateTime( FormatStyle.SHORT )
                     .withLocale( Locale.UK )
                     .withZone( ZoneId.systemDefault() );

문자열 생성

이제 해당 포매터를 사용하여 Instant의 문자열 표현을 생성하십시오.

Instant instant = Instant.now();
String output = formatter.format( instant );

콘솔로 덤프하십시오.

System.out.println("formatter: " + formatter + " with zone: " + formatter.getZone() + " and Locale: " + formatter.getLocale() );
System.out.println("instant: " + instant );
System.out.println("output: " + output );

실행할 때.

formatter: Localized(SHORT,SHORT) with zone: US/Pacific and Locale: en_GB
instant: 2015-06-02T21:34:33.616Z
output: 02/06/15 14:34


답변

public static void main(String[] args) {

    DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
            .withZone(ZoneId.systemDefault());

    System.out.println(DATE_TIME_FORMATTER.format(new Date().toInstant()));

}


답변

DateTimeFormatter.ISO_INSTANT.format(Instant.now())

이렇게하면 UTC로 변환하지 않아도됩니다. 그러나 일부 다른 언어의 시간 프레임 워크는 밀리 초를 지원하지 않을 수 있으므로 수행해야합니다.

DateTimeFormatter.ISO_INSTANT.format(Instant.now().truncatedTo(ChronoUnit.SECONDS))


답변

Instant클래스에는 영역 정보가 포함되어 있지 않으며 UNIX epoch에서 밀리 초 단위 (예 : UTC에서 1070 년 1 월 1 일) 만 타임 스탬프를 저장합니다. 따라서 날짜는 항상 구체적인 시간대로 인쇄되므로 포맷터에서 날짜를 인쇄 할 수 없습니다. 시간대를 포맷터로 설정해야하며 다음과 같이 모두 괜찮습니다.

Instant instant = Instant.ofEpochMilli(92554380000L);
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).withLocale(Locale.UK).withZone(ZoneOffset.UTC);
assert formatter.format(instant).equals("07/12/72 05:33");
assert instant.toString().equals("1972-12-07T05:33:00Z");


답변

또는 패턴에서 작성된 포맷터를 계속 사용하려면 Instant 대신 LocalDateTime을 사용할 수 있습니다.

LocalDateTime datetime = LocalDateTime.now();
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(datetime)


답변

인스턴트는 이미 UTC이며 기본 날짜 형식은 yyyy-MM-dd 입니다. 당신이 그것에 만족하고 시간대 나 형식을 엉망으로 만들고 싶지 않다면, 당신은 또한 toString()그것을 할 수 있습니다 :

Instant instant = Instant.now();
instant.toString()
output: 2020-02-06T18:01:55.648475Z

T와 Z를 원하지 않습니까? (Z는이 날짜가 UTC임을 나타냅니다. Z는 “Zulu”(일명 UTC)를 나타냅니다.

instant.toString().replaceAll("[TZ]", " ")
output: 2020-02-06 18:01:55.663763

나노초 대신 밀리 초를 원하십니까? (그래서 SQL 쿼리에 넣을 수 있습니다) :

instant.truncatedTo(ChronoUnit.MILLIS).toString().replaceAll("[TZ]", " ")
output: 2020-02-06 18:01:55.664

기타


답변

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd");
String text = date.toString(formatter);
LocalDate date = LocalDate.parse(text, formatter);

이것이 도움이 될 수 있다고 생각합니다. 즉시 대신 일종의 localdate 변형을 사용해야 할 수도 있습니다.