프로그래밍 언어/Java

[Java] time 패키지 (LocalDate, LocalTime)

happy_life 2022. 6. 29. 17:56

목차

1. 개요

2. 특징

3. 객체 생성

4. 값 가져오기

5. 필드 값 변경하기

6. 날짜와 시간 비교

7. 날짜의 차이, 시간의차이 계산하기

8. 단위 바꾸기

9. 파싱과 포맷

 

1. 개요

java에서 기존에 사용하던 Date, Calendar 클래스의 단점을 보완하기 위해 나오게 된 것이 time 패키지이다. 자바 8부터 추가되었다. 

 

2. 특징

1. time 패키지에 속한 클래스들은 String처럼 불변(immutable)하다. 즉 값이 변하면 새로운 객체를 반환한다. 따라서 멀티 쓰레드 환경에서 안전하다.

 

2. 날짜와 시간을 하나로 표현하는 Calendar 클래스와 달리 날짜와 시간을 별도로 분리하여 사용한다. 시간을 표현할 땐 LocalTime클래스, 날짜를 표현할 때는 LocalDate클래스, 날짜와 시간 모두 필요할 땐 LocalDateTime 클래스를 사용한다.

날짜 LocalTime
시간 LocalDate
날짜 + 시간 LocalDateTime

 

* 추가로 시간대(time-zone)까지 다루는 경우 ZonedDateTime 클래스라는 것도 있다.

 

 

3. 객체 생성

객체 생성을 하기 위한 가장 기본적인 방법은 now(), of() 를 사용하는 것이다. 

now()는 현재 날짜와 시간에 맞는 객체를 생성하고

of()는 원하는 날짜를 지정해 객체를 생성한다.

 

코드 예제

public class TimeEx1 {
    public static void main(String[] args) {
        //now()
        LocalDate localDate = LocalDate.now(); //2022-06-29
        LocalTime localTime = LocalTime.now(); // 21:55:02.6450

        //of()
        LocalDate wantedDate = LocalDate.of(2022, 12, 24); //2022-12-24
        LocalTime wantedTime = LocalTime.of(11, 30, 45);//11시 30분 45초
        // 원하는 날짜의 localDateTime도 만들 수 있다.
        LocalDateTime wantedLocalDateTime = LocalDateTime.of(wantedDate, wantedTime); 
    }
}

 

 

4. 값 가져오기

4.1 개요

LocalDate, LocalTime 클래스는 time 패키지의 가장 기본이며, 나머지 클래스들도 이 두 클래스의 확장이다. 따라서 이 둘을 명확히 이해해놓는 것이 좋다. LocalDate의 객체를 생성할 때는 static 메서드인 now()와 of()를 사용한다. 각각은 오버로딩을 통해 여러 가지 버젼을 제공한다. 

 

4.2 필드에서 값 가져오기 - get, getxx

getxx() 메서드 사용

클래스 리턴 타입 메서드 설명
LocalDate
LocalDateTime

int getYear()
Month getMonth() Month값(JUNE)
int getMonthValue() 월(6)
int getDayOfYear() 일년 중 몇 번째 날인지
int getDayOfMonth() 월 중 몇 번째 날인지
DayOfWeek getDayOfWeek() 요일(1:월요일~7:일요일)
boolean isLeapYear() 윤년 여부
LocalTime
LocalDateTime

int getHour() 시간
int getMinute()
int getSecond()
int getNano() 나노초

 

코드예제

public class TimeEx2 {
    public static void main(String[] args) {
        LocalDate localDate = LocalDate.now(); // 현재날짜

        int year = localDate.getYear();
        Month month = localDate.getMonth(); // JUNE
        int monthValue = localDate.getMonthValue(); // 6


        LocalTime localTime = LocalTime.now(); // 현재 시간
        
        int hour = localTime.getHour(); // 시
        int minute = localTime.getMinute(); // 분
        int second = localTime.getSecond(); // 초

    }
}

 

get(), getLong() 메서드 사용

 

TemporalField 라는 클래스의 필드를 직접 매개변수로 원하는 값을 꺼내올 수도 있다.

 

5. 필드 값 변경하기 - with, plus, minus

5.1 필드값 변경하기

with~, plus~, minus~ 메서드 사용

래스 리턴 타입 메서드 설명
LocalDate
LocalDateTime

LocalDate
LocalDateTime

with/plus/minusYears() 년 변경
with/plus/minusMonths() 월 변경
with/plus/minusWeeks() 주 변경
with/plus/minusDays() 일 변경
LocalTime
LocalDateTime

LocalTime
LocalDateTime

with/plus/minusHours() 시간 변경
with/plus/minusMinutes() 분 변경
with/plus/minusSeconds() 초 변경
with/plus/minusNanos() 나노초 변경

 

코드예제

public class TimeEx3 {
    public static void main(String[] args) {
        LocalDate localDate = LocalDate.now();//2022-06-29
        LocalTime localTime = LocalTime.now();

        LocalDate withYear = localDate.withYear(2015);//2015-06-29
        LocalDate plusYear = localDate.plusYears(1); //2023-06-29

        LocalTime minusTime = localTime.minusMinutes(30); //localTime에서 - 30분
    }
}

 

with, plus, minus 메서드 사용

with에 인자로 TemporalAdjuster나 TemporalField의 멤버를 넣어 사용할 수 있다.

 

코드예제

LocalDate adjusterYear = localDate.with(TemporalAdjusters.firstDayOfYear());
System.out.println(adjusterYear); // 당해의 첫째날

 

 

6. 날짜와 시간 비교

날짜와 시간을 비교하기위해 isAfter(), isBefore(), isEqual() 같은 편리한 메서드를 제공한다. isEqual은 연표가 다른 날짜를 비교하기 위해 있는 것으로 LocalDate에만 있으니 참고로 알아두자.

 

리턴 타입 매서드(매개 변수) 설명
LocalDate
LocalDateTime

boolean isAfter(ChronoLocalDate) 이후 날짜인지 비교
isBefore(ChronoLocalDate) 이전 날짜인지 비교
isEqual(ChrononoLocalDate) 같은 날짜인지 비교
LocalTime boolean isAfter(LocalTime) 이후 시간인지 비교
isBefore(LocalTime) 이전 시간인지 비교

 

코드예제

public class TimeEx4 {
    public static void main(String[] args) {
        LocalDate localDate1 = LocalDate.of(2021,3,5);
        LocalDate localDate2 = LocalDate.of(2021,3,6);

        System.out.println(localDate1.isAfter(localDate1)); // false
        System.out.println(localDate1.isBefore(localDate2)); // true
    }
}

 

 

7. 날짜의 차이, 시간의 차이 계산하기

날짜의 차이를 구하기 위해 Period, 시간의 차이를 계산하기위해 Duration이라는 클래스를 사용할 수 있다. 각 클래스에는 차이에 대한 정보가 들어 있고 get메서드를 통해 값을 꺼내올 수 있다.

 

between()

두 날짜 혹은 시간의 차이를 나타내는 Period와 Duration은 between 메서드로 얻을 수 있다.

 

코드 예제

public class TimeEx5 {
    public static void main(String[] args) {
        //localDate
        LocalDate localDate = LocalDate.of(2020, 6, 29);
        LocalDate localDateNow = localDate.now(); //2022-06-29


        Period periodDate = Period.between(localDate, localDateNow);

        //get 으로 값 꺼내오기
        long year = periodDate.get(ChronoUnit.YEARS); // 2
        long month = periodDate.get(ChronoUnit.MONTHS); // 0
        long day = periodDate.get(ChronoUnit.DAYS); // 0
        

        //localTime
        LocalTime localTime = LocalTime.of(10, 30, 25);//10:30:25
        LocalTime localTimeNow = localTime.now();

        Duration durationTime = Duration.between(localTime, localTimeNow);

        //get 으로 값 꺼내오기
        //duration은 get으로 꺼낼 수 있는 게 두 개 뿐이다..
        long second = durationTime.get(ChronoUnit.SECONDS);
        long nanos = durationTime.get(ChronoUnit.NANOS);
    }
}

 

until()

between은 static 메서드이고 until은 인스턴스 메서드라는 차이가 있을 뿐 거의 비슷하다. (duration을 반환하는 until은 없다.) 

 

코드 예제

public class TimeEx6 {
    public static void main(String[] args) {
        //localDate
        LocalDate localDate = LocalDate.of(2020, 6, 29);
        LocalDate localDateNow = localDate.now(); //2022-06-29


        Period periodDate = localDate.until(localDateNow); // 그냥 차이
        long pe = localDate.until(localDateNow, ChronoUnit.DAYS); // 숫자로 730일 차이
        
        //get 으로 값 꺼내오기
        long year = periodDate.get(ChronoUnit.YEARS);
        long month = periodDate.get(ChronoUnit.MONTHS);
        long day = periodDate.get(ChronoUnit.DAYS);

    }

 

8. 단위 바꾸기

Period와 Duration을 월 단위, 시간 단위 등으로 바꿀 수 있는 메서드가 있는데 아래의 표와 같다.

클래스 메서드 설명
Period toTotalMonths 월단위로 변환
Duration toDays() 일단위로 변환
toHours() 시간단위로 변환
toMillis() 밀리초단위로 변환
to Nanos() 나노초단위로 변환
 

 

코드 예제

public class TimeEx7 {
    public static void main(String[] args) {
        //Period
        LocalDate localDate = LocalDate.of(2020, 6, 29);
        LocalDate localDateNow = localDate.now(); //2022-06-29

        Period periodDate = Period.between(localDate, localDateNow);

        long totalMonth = periodDate.toTotalMonths();


        //Duration
        LocalTime localTime = LocalTime.of(10, 30, 25);//10:30:25
        LocalTime localTimeNow = localTime.now();

        Duration durationTime = Duration.between(localTime, localTimeNow);

        long toDays = durationTime.toDays();
        long toHours = durationTime.toHours();
        long toMillis = durationTime.toMillis();
        long toNanos = durationTime.toNanos();

    }
}

 

9. 파싱과 포맷

날짜와 시간을 원하는 형식으로 출력하고 해석하는 방법이 있으니 알아보자. 날짜와 시간의 파싱과 포맷에는 format()이 사용되는데, 이는 DateTimeFormatter 뿐만 아니라, LocalDate, LocalTime 클래스에도 있으니 상황에 따라 편한 쪽을 선택해 사용하면 된다.

 

9.1 포맷

 

코드 예제

public class TimeEx8 {
    public static void main(String[] args) {
        LocalDate localDate = LocalDate.of(2021, 01, 01);

        //DateTimeFormatter
        String yyyyMMdd = DateTimeFormatter.ISO_LOCAL_DATE.format(localDate); //2021-01-01

        // 직접 형식 만들기
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy.MM.dd");
        String yyyyMMdd2 = dateTimeFormatter.format(localDate); //2021.01.01

    }
}

DateTimeFormatter를 활용하여 포맷을 설정하는 코드 예제이다. 직접 포맷형식을 설정해줄 수도 있다.

 

9.2 파싱

문자열을 날짜 또는 시간으로 변환하기 위해 static 메서드인 parse()를 사용하면 된다. 

 

코드 예제

public class TimeEx9 {
    public static void main(String[] args) {
        //DateTimeFormatter static 사용
        LocalDate localDate = LocalDate.parse("2022-06-29", DateTimeFormatter.ISO_LOCAL_DATE);

        //DateTimeFormatter ofPattern 사용
        DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy.MM.dd");
        LocalDate localDate2 = LocalDate.parse("2015.10.22", pattern);

    }
}