[Java8 Time API] LocalTime 정리

kkatal_chae·2023년 1월 15일
0

Java8 Time API

목록 보기
2/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 에서 시간대 및 타임존에 대한 참조를 가진 시간과 날짜를 다루는 클래스


객체의 생성

// 현재 시간 객체 생성 
LocalTime localTime = LocalTime.now(); // 11:57:33.000

LocalTime localTIme = LocalTime.of(12, 30, 0); // 

💡 LocalDate 클래스는 public 생성자를 제공하지 않기 때문에 객체를 생성할 때는 now() , of() 와 같은 정적 메소드를 사용하도록 되어 있습니다.


객체의 형변환

// localTime -> String 
localTime.format( DateTimeFormatter.ISO_LOCAL_TIME ); // 11:07:27.0000000000
localTime.format( DateTimeFormatter.ofPattern( "HH:mm:ss" ); // 11:07:27

// String -> localTime 
LocalTime.parse( "22:00:00", DateTimeFormatter.ofPattern( "HH:mm:ss" ) ); // @param String, DateTimeFormatter

유용한 메서드

// 시간, 분, 초 나노초 얻기 
loalTime.getHour(); // 11
localTime.getMinute(); // 25
localTime.getSecond(); // 38
localTime.getNano(); // 879975840

// 시간 비교 
LocalTime time1 = LocalTime.of( 12, 30, 0 );
LocalTime time2 = LocalTime.of( 13, 40, 0 );

time1.isAfter( time2 ); // false ( @param LocalTime )
time1.isBefore( time2 ); // true

// 특정 시간에서 특정 부분 ( 시간, 분, 초 ) 변경한 객체 얻기 
LocalTime localTime = LocalTime.of( 12, 30, 0); 

localTime.with( ChronoField.MINUTE_OF_HOUR, 40 ); // 12:40 ( @param TemporalField field, long newValue )
localTime.withHour( 13 ); // 13:30
localTime.withMinute( 40 ); // 12:40
localTime.withSecond( 40 ); // 12:30:40
localTime.withNano( 40 ); // 12:30:00.000000040

// 시간 더하기 
localTime.plus( 2, ChronoUnit.HOURS ); // 14:30 ( @param long amountToAdd, TeporalUnit unit )
localTime.plusHours( 2 ); // 14:30 
localTime.plusMinutes( 30 ); // 13:00 
localTime.plusSecond( 30 ); // 12:30:30 
localTime.plusNanos( 30 ); // 12:30:00.000000030

// 시간 빼기
localTime.minus( 2, ChronoUnit.HOURS ); // 10:30 ( @param long amountToSubtract, TeporalUnit unit )
localTime.minusHours( 2 ); // 10:30 
localTime.minusMinutes( 30 ); // 12:00 
localTime.minusSecond( 30 ); // 12:29:30 
localTime.minusNanos( 30 ); // 12:29:59.999999970

// 두 시간 차이 
Duration duration = Duration.between( time1, time2 ); 
duration.getNano(); // 0 
duration.getSeconds(); // 4200

long diffHours = ChronoUnit.HOURS.between( time1, time2 ); // 1
long diffMinutes = ChronoUnit.MINUTES.between( time1, time2 ); // 70
long diffSeconds = ChronoUnit.SECONDS.between( time1, time2 ); // 4200 

ChronoField

열거체 상수설명
ERA시대
YEAR연도
MONTH_OF_YEAR
DAY_OF_MONTH
DAY_OF_WEEK요일 (월요일:1, 화요일:2, ..., 일요일:7)
AMPM_OF_DAY오전/오후
HOUR_OF_DAY시(0~23)
CLOCK_HOUR_OF_DAY시(1~24)
HOUR_OF_AMPM시(0~11)
CLOCK_HOUR_OF_AMPM시(1~12)
MINUTE_OF_HOUR
SECOND_OF_MINUTE
DAY_OF_YEAR해당 연도의 몇 번째 날 (1~365, 윤년이면 366)
EPOCH_DAYEPOCH(1970년 1월 1일)을 기준으로 몇 번째 날

💡 LocalDateTime 은 LocalDate 와 LocalTime 을 결합하여 사용하는 것으로 생각하면 쉽다.

참고

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

LocalTime (Java Platform SE 8 )

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

코딩교육 티씨피스쿨

0개의 댓글