자바에서 시간이나 날짜를 다뤄야하는 일이 있다면 가장 먼저 구글에 자바 현재 시간
과 같은 형식으로 검색을 할 것 같습니다.
그럼 다수의 블로그들이 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
열거체 상수 | 설명 |
---|---|
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_DAY | EPOCH(1970년 1월 1일)을 기준으로 몇 번째 날 |
💡 LocalDateTime 은 LocalDate 와 LocalTime 을 결합하여 사용하는 것으로 생각하면 쉽다.
[Java8 Time API] LocalDate, LocalTime, LocalDateTime 사용법
LocalTime (Java Platform SE 8 )