[Java8 Time API] LocalDate 정리

kkatal_chae·2023년 1월 14일
0

Java8 Time API

목록 보기
1/2
post-thumbnail

자바에서 시간이나 날짜를 다뤄야하는 일이 있다면 가장 먼저 구글에 자바 현재 시간 과 같은 형식으로 검색을 할 것 같습니다.

그럼 다수의 블로그들이 calendar 클래스나 date 클래스를 사용하여 설명하고 있을 겁니다.

자바 8 이하의 버전을 사용하고 있다면 사용해야겠지만 대부분 자바 8 정도는 사용하고 있기 때문에 자바 8 부터 사용하고 있는 java.time 패키지를 사용하는 것이 바람직하다.


java.time 패키지를 사용해야 하는 이유

그렇다면 왜 java.time 패키지를 사용해야 하는가?

자바 8 이전의 [util.Date](http://util.Date) 클래스는 변하기 쉬운( mutable ) 클래스이기 때문에 스레드 안전 ( thread safe ) 하지 않습니다.

변하기 쉬우면 좋은거 아닌가? 라고 생각할 수도 있습니다.

아주 간단한 프로그램이라면 상관없을 수도 있지만 규모가 있거나 어플리케이션에서는 스레드 안전하다는 것은 굉장히 중요합니다.

여러 작업이 동작하면서 내가 예상치 못하게 다른 스레드에서 그 값을 수정하여 다른 값이 전달될 가능성이 있기 때문에 java.time 패키지의 클래스들을 사용해야 합니다.

버그가 발생할 여지가 많습니다. 타입 안정성이 없고, 월이 0 부터 시작하는 등의 불편함을 가지고 있습니다.

Calendar birthDay = new GregorianCalendar( 2022, 12, 25 );
birthDay.getTime(); // Wed Jan 25 00:00:00 GMT 2023

위의 코드를 입력한 개발자는 2022 년 12 월 25 일의 날짜 객체를 원했겠지만 실제로 얻은 날짜는 2023년 1월 25일이라는 결과다. 이렇듯 사용하기에 불편한 점이 많다.


java.time 패키지

자바 8 버전에서 공개된 java.time 패키지에는 다음과 같은 클래스들을 제공하고 있다.

Instant : 타임스탬프 ( 기계용 시간, EPOCH )

LocalDate : 시간이 없는 날짜 ( 타임존에 대한 참조가 없음 )

LocalTime : 날짜가 없는 시간 ( 타임존에 대한 참조가 없음 )

LocalDateTime : 날짜와 시간을 결합한 클래스

ZonedDateTime : UTC 에서 시간대 및 타임존에 대한 참조를 가진 시간과 날짜를 다루는 클래스

그 중 날짜를 다룰 때 쓰이는 LocalDate 클래스에 대해서 먼저 알아보도록 하자.


객체의 생성

기본적으로 java.time 패키지의 클래스들은 불변 클래스이기 때문에 한번 생성되면 내부 필드값을 바꿀 수 없기 때문에 public 생성자를 제공하지 않는다.

LocalDate

// 현재 날의 객체 얻기 
LocalDate localDate = LocalDate.now(); // 2022-12-25 

// 특정 일자의 날짜 가져오는 정적 메소드 
LocalDate localDate = LocalDate.of( 2022, 12, 25 ); 

💡 LocalDate.parse 은 기본적으로 yyyy-MM-dd 형식을 기준으로 날짜 정보를 가져오며 DateTimeFormatter 를 설정하여 다른 형식을 사용할 수 있다.


객체의 형변환

// LocalDate -> String 
LocalDate.of( 2022, 12, 12 ).format( DateTimeFormatter.BASIC_ISO_DATE); // 20221212

// String -> LocalDate 
LocalDate.parse( "20221212", DateTimeFormatter.BASIC_ISO_DATE); // 2022-12-12 
LocalDate localDate = LocalDate.parse( "2022-12-25" ); // 2022-12-25

// LocalDate -> java.sql.Date
Date.valueOf( LocalDate.of( 2022, 12, 12 ) ); // 2022-12-12 

// java.sql.Date -> LocalDate
new Date( System.currentTimeMillis() ).toLocalDate(); // 2022-12-12

유용한 메소드

// 특정 날짜의 요일 구하기 
LocalDate.of( 2022, 12, 12 ).getDayOfWeek(); // MONDAY

// 특정 날짜로부터 일, 월, 주, 연 차이 나는 날짜 구하기 
localDate.minusDays( 5 ); // @param long daysToSubtract
localDate.minusMonths( 5 ); // @param long daysToSubtract
localDate.minusWeeks( 5 ); // @param long daysToSubtract
localDate.minusYears( 5 ); // @param long daysToSubtract

// 특정 날짜로부터 몇 일 이후 날짜 구하기 ( 위와 유사 ) 
localDate.plusDays( 7 ); // @param long amountToAdd 

// 특정 날짜가 해당하는 주의 특정 요일 일자 구하기 
localDate.with( DayOfWeek.FRIDAY); // 2022-12-16 ( @param DayOfWeek )

// 특정 날짜에서 특정 부분만 바꾸기 
LocalDate localDate = LocalDate.now(); // 2022-12-12

localDate.withDayOfMonth( 31 ); // 2022-12-31 ( @param int dayOfMonth )
localDate.withMonth( 1 ); // 2022-01-12 ( @param int month )
localDate.withYear( 2023 ); // 2023-12-12 ( @param int year )

// 윤년 여부 
localDate.isLeapYear(); // false 

// 해당 월의 첫째 날 구하기 
localDate.withDayOfMonth( 1 );

// 해당 월의 마지막 날 구하기 
localDate.withDayOfMonth( localDate.lengthOfMonth() );

// 두 날짜 사이의 간격 구하기 
LocalDate start = LocalDate.of( 2021, 10, 1 );
LocalDate end = LocalDate.of( 2022, 12, 31 );

Period diff = Period.between( start, end );

diff.getYears(); // 1
diff.getMonths(); // 2 
diff.getDays(); // 30 

// ChronoUnit 을 이용한 두 날짜 사이 간격 구하기
long diffMonth = ChronoUnit.MONTHS.between( start, end ); // 14
long diffWeek = ChronoUnit.WEEKS.between( start, end ); // 65
long diffDay = ChronoUnit.DAYS.between( start, end ); // 456

참고

[Java8 Time API] Duration과 Period 사용법 (+ChronoUnit)

LocalDate (Java Platform SE 8 )

Java Date & Time, 제대로 다루기

[Java8 Time API] LocalDate, LocalTime, LocalDateTime 사용법

0개의 댓글