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

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

자바8에 추가된 Time 패키지에는 DurationPeriod라는 상당히 비슷해 보이는 2개의 클래스가 있습니다. 이 두개의 클래스는 둘 다 시간의 길이을 나타내기 위해서 사용되는데요. Duration은 두 “시간” 사이의 간격을 나타내는 반면에 Period는 두 “날짜” 사이의 간격을 나타낸다는 차이점이 있습니다. 이 게 무슨 말인지 예제를 통해서 살펴보도록 하겠습니다.

Duration

먼저 Duration 클래스는 두 시간 사이의 간격을 초나 나노 초 단위로 나타냅니다. 다음 예제는 10시 35분 40초10시 36분 50.0000008초 사이의 Duration을 생성 후, 초와 나노 초를 출력하고 있습니다. Duration 클래스의 between() 정적 메서드에 시작 시간과 종료 시간을 넘기면 두 시간의 간격을 나타내는 Duration 객체를 생성해줍니다.

LocalTime start = LocalTime.of(10, 35, 40);
LocalTime end = LocalTime.of(10, 36, 50, 800);

Duration duration = Duration.between(start, end);

System.out.println("Seconds: " + duration.getSeconds());
System.out.println("Nano Seconds: " + duration.getNano());
Seconds: 70
Nano Seconds: 800

시작 시간과 종료 시간 없이 Duration 클래스의 ofXxx() 정적 메서드를 사용하면 다음과 같이 바로 Duration 클래스를 생성할 수 있습니다. Duration 클래스를 통해 제어할 수 있는 가장 큰 시간 단위는 “일” 입니다. 그보다 큰 시간 단위는 Period 클래스를 통해서 제어가 가능하며 다음 섹션에서 자세히 다루도록 하겠습니다.

Duration ofMinutes = Duration.ofMinutes(1);
System.out.printf("1 minute is %d seconds\n", ofMinutes.getSeconds());

Duration ofHours = Duration.ofHours(1);
System.out.printf("1 hour is %d seconds\n", ofHours.getSeconds());

Duration ofDays = Duration.ofDays(1);
System.out.printf("1 day is %d seconds\n", ofDays.getSeconds());
1 minute is 60 seconds
1 hour is 3600 seconds
1 day is 86400 seconds

DurationPnDTnHnMn.nS 포맷을 사용하고 있으며, parse() 정적 메소드를 사용해서 이 포맷을 따르는 문자열로 부터 객체를 생성할 수 있습니다.

Duration duration = Duration.parse("PT10H36M50.008S");
System.out.println(duration);
System.out.printf("Seconds: %d, Nano Secodns: %d\n", duration.getSeconds(), duration.getNano());
PT10H36M50.008S
Seconds: 38210, Nano Secodns: 8000000

Period

한편, Period 클래스는 두 날짜 사이의 간격을 년/월/일 단위로 나타냅니다. Duration과 마찬가지로 between() 정적 메소드를 제공하고 있으며, 시작 날짜와 종료 날짜를 나타내는 두 개의 LocalDate 객체를 인자로 받습니다. 아래 예제는 세계 2차 대전이 얼마동안 지속이 되었는지를 구하는 코드입니다. 1939년 9월 1일에 시작되어 1945년 9월 2일에 끝난 이 전쟁은 6년 1일간 치뤄졌습니다.

LocalDate startDate = LocalDate.of(1939, 9, 1);
LocalDate endDate = LocalDate.of(1945, 9, 2);

Period period = Period.between(startDate, endDate);

System.out.println("Years: " + period.getYears());
System.out.println("Months: " + period.getMonths());
System.out.println("Days: " + period.getDays());
Years: 6
Months: 0
Days: 1

시작 날짜와 종료 날짜 없이 of() 메서드를 통해서 바로 Period 객체를 생성할 수도 있습니다.

Period period = Period.of(6, 0, 1);

System.out.println("Years: " + period.getYears());
System.out.println("Months: " + period.getMonths());
System.out.println("Days: " + period.getDays());
Years: 6
Months: 0
Days: 1

PeroidPnYnMnD 포맷을 사용하고 있으며, parse() 정적 메소드를 사용해서 이 포맷을 따르는 문자열로 부터 객체를 생성할 수 있습니다.

Period period = Period.parse("P6Y1D");
System.out.println(period);
System.out.println("Years: " + period.getYears());
System.out.println("Months: " + period.getMonths());
System.out.println("Days: " + period.getDays());
P6Y1D
Years: 6
Months: 0
Days: 1

ChronoUnit

Duration 또는 Period 객체를 생성하지 않고도 간편하게 특정 시간 단위로 시간의 길이를 구하는 방법이 있습니다. 바로 아래 예체처럼 ChronoUnit을 사용하면 됩니다.

LocalDate startDate = LocalDate.of(1939, 9, 1);
LocalDate endDate = LocalDate.of(1945, 9, 2);

long months = ChronoUnit.MONTHS.between(startDate, endDate);
long weeks = ChronoUnit.WEEKS.between(startDate, endDate);
long days = ChronoUnit.DAYS.between(startDate, endDate);

System.out.println("Months: " + months);
System.out.println("Weeks: " + weeks);
System.out.println("Days: " + days);

LocalTime startTime = LocalTime.of(10, 35, 40);
LocalTime endTime = LocalTime.of(10, 36, 50, 800);

long hours = ChronoUnit.HOURS.between(startTime, endTime);
long minutes = ChronoUnit.MINUTES.between(startTime, endTime);
long seconds = ChronoUnit.SECONDS.between(startTime, endTime);

System.out.println("Hours: " + hours);
System.out.println("Minutes: " + minutes);
System.out.println("Seconds: " + seconds);
Months: 72
Weeks: 313
Days: 2193
Hours: 0
Minutes: 1
Seconds: 70

이상으로 Java8에서 시간의 길이를 다루는 다양한 방법에 대해서 알아보았습니다.

참고

This work is licensed under CC BY 4.0 CC BY

개발자를 위한 뉴스레터

달레가 정리한 AI 개발 트렌드와 직접 만든 콘텐츠를 전해드립니다.

Discord