[JAVA] 자바(java.time) 날짜, 시간 구하기 (LocalDate, LocalTime, LocalDateTime 사용법)


java.time

  • Java 1.8 (자바 8) 이전에서는 보통 Calendar를 사용하고, Date/long/String 으로 변환후 사용하는 방법을 많이 사용함.

  • Java 1.8 (자바 8) 후에는 LocalDate, LocalTime, LocalDateTime 등이 추가되어 날짜, 시간관련하여 코드를 짜기가 더 쉬워짐


날짜와 시간 객체 생성


날짜 - LocalDate

LocalDate currentDate = LocalDate.now();    // 컴퓨터의 현재 날짜 정보를 저장한 LocalDate 객체를 리턴한다.
LocalDate targetDate = LocalDate.of(int year, int month, int dayOfMonth);   // 파라미터로 주어진 날짜 정보를 저장한 LocalDate 객체를 리턴한다. 결과 : 1986-11-22
리턴 타입 메소드(매개변수) 설명
int getYear()
Month getMonth() Month 열거 값(JANUARY, FEBRUARY, MARCH ..)
int getMonthValue() 월(1, 2, 3 ..)
int getDayOfYear() 일년의 몇 번째 일
int getDayOfMonth() 월의 몇 번째 일
DayOfWeek getDayOfWeek() 요일(MONDAY, TUESDAY, WEDNESDAY..)
boolean isLeapYear() 윤년여부

시간 - LocalTime

LocalTime currentTime = LocalTime.now();    // 컴퓨터의 현재 시간 정보. 결과 : 16:24:02.408 
LocalTime targetTime = LocalTime.of(int hour, int minute, int second, int nanoOfSecond); // 파라미터로 주어진 시간 정보를 저장한 LocalTime 객체를 리턴한다.
리턴 타입 메소드(매개변수) 설명
int getHour() 시간
int getMinute()
int getSecond()
int getNano() 나노초

LocalDateTime ()날짜와 시간 정보가 모두 필요하다면)

 LocalDateTime currentDateTime = LocalDateTime.now();    // 컴퓨터의 현재 날짜와 시간 정보.
 LocalDateTime targetDateTime = LocalDateTime.of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond);

ZonedDateTime

  • ISO-8601 달력 시스템에서 정의하고 있는 타임존의 날짜와 시간을 저장하는 클래스이다.

  • 결과는 2020-06-01T16:54:05.739+09:00[Asia/Seoul]와 같고, 맨 뒤에 +09:00[Asia/Seoul] 협정세계시와의 시차(+9시간)와 ZoneId(Asia/Seoul) 정보가 붙는다.

ZonedDateTime utcDateTime = ZonedDateTime.now(ZoneId.of("UTC"));
ZonedDateTime seoulDateTime = ZonedDateTime.now(ZoneId.of("Asia/Seoul"));
리턴 타입 메소드(매개변수) 설명
ZoneId getZone() ZoneId를 리턴(Asia/Seoul)
ZoneOffset getOffset() UTC와의 시차를 리턴(+09:00)


날짜와 시간 사용하기


날짜 더하고, 빼기

  • 년, 월, 일, 주를 더하거나 뺄 수 있다.
LocalDateTime currentDateTime = LocalDateTime.now();
LocalDateTime targetDateTime = currentDateTime
        .plusYears(long)       // 년도 더하기
        .minusYears(long)      // 년도 빼기
        .plusMonths(long)      // 월 더하기 
        .minusMonths(long)     // 월 빼기
        .plusDays(long)        // 일 더하기 
        .minusDays(long)       // 일 빼기
        .plusWeeks(long)       // 주 더하기
        .minusWeeks(long);     // 주 빼기


시간 더하고, 빼기

  • 시간, 분, 초, 나노초를 더하거나 뺄 수 있다.
LocalDateTime currentDateTime = LocalDateTime.now();
LocalDateTime targetDateTime = currentDateTime
        .plusHours(long)       // 시간 더하기
        .minusHours(long)      // 시간 빼기
        .plusMinutes(long)     // 분 더하기 
        .minusMinutes(long)    // 분 빼기
        .plusSeconds(long)     // 초 더하기 
        .minusSeconds(long)    // 초 빼기
        .plusNanos(long)       // 나노초 더하기
        .minusNanos(long);     // 나노초 빼기


날짜와 시간을 변경

  • 년, 월, 월의 몇 번째 일인지, 년의 몇번 번째 일인지를 변경할 수 있다.
LocalDateTime currentDateTime = LocalDateTime.now();
LocalDateTime targetDateTime = currentDateTime
                .withYear(int)          // 년도를 변경
                .withMonth(int)         // 월 변경
                .withDayOfMonth(int)    // 월의 일을 변경
                .withDayOfYear(int);    // 년도의 일을 변경
                .with(TemporalAdjuster adjuster) // 현재 날짜를 기준으로 상대적인 날짜로 변경
  • 마지막에 .with(TemporalAdjuster adjuster) 메소드를 사용하면 현재 날짜를 기준으로 년도의 첫 번째 일, 마지막 일, 월의 첫 번째 일, 마지막일, 지난 요일 및, 돌아오는 요일 등 상대적인 날짜로 변경을 할 수 있다
LocalDateTime currentDateTime = LocalDateTime.now();
LocalDateTime targetDateTime = currentDateTime
        .with(TemporalAdjusters.firstDayOfYear())       // 이번 년도의 첫 번째 일(1월 1일)
        .with(TemporalAdjusters.lastDayOfYear())        // 이번 년도의 마지막 일(12월 31일)
        .with(TemporalAdjusters.firstDayOfNextYear())   // 다음 년도의 첫 번째 일(1월 1일)
        .with(TemporalAdjusters.firstDayOfMonth())      // 이번 달의 첫 번째 일(1일)
        .with(TemporalAdjusters.lastDayOfMonth())       // 이번 달의 마지막 일
        .with(TemporalAdjusters.firstDayOfNextMonth())  // 다음 달의 첫 번째 일(1일)
        .with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)) // 이번 달의 첫 번째 요일(여기서는 월요일)
        .with(TemporalAdjusters.lastInMonth(DayOfWeek.FRIDAY))  // 이번 달의 마지막 요일(여기서는 마지막 금요일)
        .with(TemporalAdjusters.next(DayOfWeek.FRIDAY))       // 다음주 금요일
        .with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY)) // 다음주 금요일(오늘 포함. 오늘이 금요일이라면 오늘 날짜가 표시 된다.)
        .with(TemporalAdjusters.previous(DayOfWeek.FRIDAY))     // 지난주 금요일
        .with(TemporalAdjusters.previousOrSame(DayOfWeek.FRIDAY));// 지난주 금요일(오늘 포함)


날짜 비교

  • LocalDate, LocalDateTime

  • isBefore(ChronoLocalDate other), isEqual(ChronoLocalDate other), isAfter(ChronoLocalDate other) 메소드를 사용해 날짜를 비교할 수 있다. 리턴 타입은 boolean이다.

LocalDateTime startDateTime = LocalDateTime.now();
LocalDateTime endDateTime = LocalDateTime.of(2020, 6, 1, 23, 59, 59);

// startDateTime이 endDateTime 보다 이전 날짜 인지 비교
startDateTime.isBefore(endDateTime);    // true

// 동일 날짜인지 비교
startDateTime.isEqual(endDateTime); // false

// startDateTime이 endDateTime 보다 이후 날짜인지 비교
startDateTime.isAfter(endDateTime); // false


시간 비교

  • LocalTime과 LocalDateTime

  • isBefore(LocalTime other), isAfter(LocalTime other) 메소드를 사용해 시간을 비교할 수 있다. 리턴 타입은 boolean이다.

LocalTime startTime = LocalTime.now();  // 23:52:35.603
LocalTime endTime = LocalTime.of(23, 59, 59);

// startTime이 endTime 보다 이전 시간 인지 비교
startTime.isBefore(endTime);    // true

// startTime이 endTime 보다 이후 시간 인지 비교
startTime.isAfter(endTime); // false


날짜 차이 계산

  • LocalDate는 until(ChronoLocalDate endDate) 메소드를 사용해서 날짜 차이를 계산

  • 리턴 타입은 java.time.Period

  • Period 클래스의 getYears(), getMonths(), getDays() 메소드를 사용해서 년도 차이, 월의 차이, 일의 차이를 계산

LocalDate currentDate = LocalDate.now(); // 2020-04-02
LocalDate targetDate = LocalDate.of(2020,5,5);

Period period = currentDate.until(targetDate);

period.getYears();      // 0년
period.getMonths();     // 1개월
period.getDays();       // 3일 차이
  • Period 클래스의 between(LocalDate startDate, LocalDate endDate) 메소드를 사용해서도 날짜 차이를 구할 수 있고, 리턴 타입은 Period 이다.
LocalDate startDate = LocalDate.now(); // 2020-04-02
LocalDate endDate = LocalDate.of(2020,5,5);

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

period.getYears();      // 0년
period.getMonths();     // 1개월
period.getDays();       // 3일 차이


시간 차이 계산

  • LocalDate, LocalTime, LocaDateTime은 until(Temporal end, TemporalUnit unit) 메소드를 사용하여 시간 차이를 계산

  • 리턴 타입은 long

  • 인터페이스의 구현체로 자바가 제공해주는 ChronoUnit을 사용

LocalTime startTime = LocalTime.now();  // 00:35:39
LocalTime endTime = LocalTime.of(12,59,00);

startTime.until(endTime, ChronoUnit.HOURS); 
  • 다른 방법으로 java.time.Duration 클래스의 between(Temporal start, Temporal end) 메소드를 사용해서도 시간 차이를 구할 수 있다.

  • 리턴 타입은 Duration

LocalTime startTime = LocalTime.now();  // 00:35:39
LocalTime endTime = LocalTime.of(12,59,00);

Duration duration = Duration.between(startTime, endTime);
duration.getSeconds();      // 초의 차이
duration.getNano();         // 나노초의 차이


전체 시간을 기준으로 차이 계산

  • Period 클래스의 between()메소드를 사용해서 계산하는 경우

  • 예를 들어 계산 결과가 1개월 3일 차이 일때 33일이 나오도록 전체 일을 구하는 방법은 ChronoUnit 클래스의 between(Temporal start, Temporal end) 메소드를 사용하면 되고, 리턴 타입은 long 이다.

클래스 설명
ChronoUnit.YEARS 전체 년 차이
ChronoUnit.MONTHS 전체 월 차이
ChronoUnit.WEEKS 전체 주 차이
ChronoUnit.DAYS 전체 일 차이
ChronoUnit.HOURS 전체 시간 차이
ChronoUnit.SECONDS 전체 초 차이
ChronoUnit.MILLIS 전체 밀리초 차이
ChronoUnit.NANOS 전체 나노초 차이
LocalDate startDate = LocalDate.now(); // 2020-04-02
LocalDate endDate = LocalDate.of(2020,5,5);

ChronoUnit.DAYS.between(startDate, endDate); // 결과 : 33 (1개월 3일)


날짜 포맷하기

  • format(DateTimeFormatter formatter) 메소드를 사용해서 원하는 문자열로 변환시킬 수 있다.
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy년 M월 d일 a h시 m분");
String nowString = now.format(dateTimeFormatter);   // 결과 : 2020년 4월 2일 오전 1시 4분


Reference