관리 메뉴

A seeker after truth

[java] 날짜 및 시간 표현을 어떻게 할까? 본문

Projects/날씨-코디앱 개발 과정

[java] 날짜 및 시간 표현을 어떻게 할까?

dr.meteor 2020. 7. 19. 18:04

에는 java.time 패키지의 LocalDate, LocalTime, LocalDateTime(날짜&시간 같이 필요한 경우)를 사용하자.

timezone까지 다뤄야 하면 ZonedDateTime 클래스를 사용한다.

 

이 패키지에 속한 클래스들의 가장 큰 특징은 스트링 클래스처럼 immutable란 것이다. 그래서 날짜나 시간을 변경하는 메서드들은 기존의 객체를 변경하는 대신 항상 변경된 새로운 객체를 반환한다.기존 Calendar 클래스는 변경 가능하므로, 멀티 쓰레드 환경에서 안전하지 못하다.

멀티 쓰레드 환경에선 동시에 여러 쓰레드가 같은 객체에 접근할 수 있기 때문에, 변경 가능한 객체는 데이터가 잘못될 가능성이 있으며, 이를 스레드에 안전하지 않다고 한다.

 

이 패키지는 JDK 1.8부터 도입된 것인데, 호환성 때문에 옛날 것인 Date, Calendar 클래스도 계속 쓰일 것이다.

 

 

Calendar는 ZonedDateTime처럼 날짜, 시간, 시간대까지 모두 갖고 있다.

Date와 유사한 클래스로는 Instant가 있는데, 이 클래스는 날짜와 시간을 초단위(나노초)로 표현한다. 즉 타임스탬프에 해당한다. 날짜와 시간을 하나의 정수로 표현한 값은 날짜와 시간의 차이를 계산하거나 순서를 비교하는데 유리해서 데베에 많이 사용된다.

Year, YearMonth, MonthDay 클래스는 날짜를 더 세부적으로 다룰 수 있다.

 

날짜/ 시간 간격을 표현하는 클래스가 따로 있긴 하다. Period, Duration이 각각에 해당한다.

그 차이를 얻을 수 있는 메서드는 between()에 해당한다.

LocalDate date1 = LocalDate.of(2014,1,1);
LocalDate date2 = LocalDate.of(2015,12,31);
Period pe = Period.between(date1, date2);
LocalTime time1 = LocalTime.of(00,00,00);
LocalTime time2 = LocalTime.of(12,34,56);
Duration du = Duration.between(time1, time2);

 

이 패키지에 속한 클래스의 객체를 생성하는 가장 기본적인 방법은 now(), of()를 사용하는 것이다. 전자는 현재 날짜와 시간을 저장하는 객체를 생성. 후자는 해당 필드 값을 순서대로 지정해주면 된다. 각 클래스마다 다양한 종류의 of()가 정의되어 있다.

LocalDate date = LocalDate.of(2015, 11, 13);

 

 

 

[날짜와 시간의 비교]

LocalDate, LocalTime에 대해 compareTo() 보다 비교하기 편한 메서드를 제공한다.

boolean isBefore(ChronoLocalDate other)

boolean isAfter(ChronoLocalDate other)

boolean isEqual(ChronoLocalDate other)

equals()가 있는데도 isEqual()을 제공하는 이유는 연표(chronology)가 다른 두 날짜(날짜만 비교한다)를 비교하기 위해서다.

equals()의 경우 모든 필드가 일치해야 한다.

LocalDate kDate = LocalDate.of(1999, 12, 31);
JapaneseDate jDate = JapaneseDate.of(1999, 12, 31);
System.out.println(kDate.equals(jDate)); //false
System.out.println(kDate.isEqual(jDate)); //true

 

그리고 스프링에는 이런 어노테이션이 있다.

 

import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;

 

이를 이용하면,

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseTimeEntity {

    @CreatedDate
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime modifiedDate;

}

자바의 저런 코드, 클래스를 이용하지 않고도 훨씬 편하게 뭔가를 할 수 있는 것으로 보이는데...

 

 

[포맷과 파싱]

1. java.time.format 패키지에서 지원하는 양식에 따라 매우 다양하게 포맷팅 가능

2. parse() 메서드가 다양하게 오버로딩 되어있고, 자주 쓰이는 것은 자바의 정석 575쪽에...