날짜와 시간 비교 - LocalDateTime
isAfter()
주어진 날짜를 기준으로 인자로 들어온 파라미터 값을 비교하여, 주어진 날짜가 파라미터보다 앞서있다면 true를 반환한다.
LocalDateTime plusDays = LocalDateTime.now().plusDays(1); // 2023-09-12
LocalDateTime now = LocalDateTime.now(); // 2023-09-11
LocalDateTime now2 = LocalDateTime.now(); // 2023-09-11
System.out.println(now.isAfter(plusDays)); // false -> now(2023-09-11) > plusDays(2023-09-12) 와 같음
System.out.println(now.isAfter(now2)); // false (주어진 날짜(now)와 파라미터의 값(now2)가 같은경우 false)
System.out.println(plusDays.isAfter(now)); // true -> plusDays(2023-09-12) > now(2023-09-11) 와 같음
isBefore()
주어진 날짜를 기준으로 인자로 들어온 파라미터 값을 비교하여, 주어진 날짜가 파라미터보다 뒤라면 true를 반환한다.
LocalDateTime plusDays = LocalDateTime.now().plusDays(1); // 2023-09-12
LocalDateTime now = LocalDateTime.now(); // 2023-09-11
LocalDateTime now2 = LocalDateTime.now(); // 2023-09-11
System.out.println(now.isBefore(plusDays)); // true -> now(2023-09-11) < plusDays(2023-09-12) 와 같음
System.out.println(now.isBefore(now2)); // false (주어진 날짜(now)와 파라미터의 값(now2)가 같은경우 false)
System.out.println(plusDays.isBefore(now)); // false -> plusDays(2023-09-12) < now(2023-09-11) 와 같음
compareTo()
주어진 날짜를 기준으로 인자로 들어온 파라미터 값을 비교하여
주어진 날짜가 더 작으면 -1
같으면 0
주어진 날짜가 더 크면 1 을 반환한다.
LocalDateTime plusDays = LocalDateTime.now().plusDays(1); // 2023-09-12
LocalDateTime now = LocalDateTime.now(); // 2023-09-11
LocalDateTime now2 = LocalDateTime.now(); // 2023-09-11
System.out.println(now.compareTo(plusDays)); // now가 plusDays보다 뒤이기 때문에 -1
System.out.println(now.compareTo(now2)); // now와 now2는 같은 날짜이기 때문에 0
System.out.println(plusDays.compareTo(now)); // now보다 plusDays가 앞이기 때문에 1
Instant
Instant는 에포크 타임(1970-01-01 00:00:00 UTC)부터 경과된 시간을 나노초 단위로 표현한다. 사람에겐 불편하지만, 단일 진법으로만 다루기 때문에 계산하기 쉽다.
Instant now = Instant.now();
long epochSecond = now.getEpochSecond();
int nano = now.getNano();
long epochMilli = now.toEpochMilli();
System.out.println("Instant.now() = " + now);
System.out.println("epochSecond = " + epochSecond);
System.out.println("nano = " + nano);
System.out.println("epochMilli = " + epochMilli);
결과
Instant.now() = 2023-09-11T06:23:07.660663600Z
epochSecond = 1694413387
nano = 660663600
epochMilli = 1694413387660
위 코드와 같이 Instant는 시간을 초 단위와 나노초 단위로 나누어 저장한다. 오라클 데이터베이스의 타임스탬프처럼 밀리초 단위의 EPHCH TIME을 필요로 하는 경우를 위해 toEpochMilli()가 정의되어 있다.
주의
Instant는 항상 UTC(+00:00)를 기준으로 하기 때문에, LocalTime과 차이가 있을 수 있다.
아래에서 Instant <-> LocalDateTIme 변환하는 방법을 알아보자
LocalDateTime과 ZonedDateTime
LocalDate와 LocalTime을 합쳐 놓은 것이 LocalDateTime이고, LocalDateTime에 시간대(time zone)을 추가한 것이 ZonedDateTime이다.
LocalDate + LocalTime = LocalDateTime
LocalDateTime + TimeZone = ZonedDateTime
ZonedDateTime zonedDateTime = ZonedDateTime.now(); // ZoneId는 Clock.systemDefaultZone()로 세팅된다
LocalDateTime localDateTime = LocalDateTime.now();
ZoneId seoulZoneId = ZoneId.of("Asia/Seoul");
ZonedDateTime seoulZonedDateTime = ZonedDateTime.now(seoulZoneId);
ZoneId newYorkZoneId = ZoneId.of("America/New_York");
ZonedDateTime newYorkZonedDateTime = ZonedDateTime.now(newYorkZoneId);
System.out.println("zonedDateTime = " + zonedDateTime);
System.out.println("localDateTime = " + localDateTime);
System.out.println("seoulZonedDateTime = " + seoulZonedDateTime);
System.out.println("newYorkZonedDateTime = " + newYorkZonedDateTime);
결과
zonedDateTime = 2023-09-11T15:37:32.543382300+09:00[Asia/Seoul]
localDateTime = 2023-09-11T15:37:32.556348200
seoulZonedDateTime = 2023-09-11T15:37:32.556348200+09:00[Asia/Seoul]
newYorkZonedDateTime = 2023-09-11T02:37:32.557345100-04:00[America/New_York]
위와같이 zonedDateTime은 timeZone +09:00[Asia/Seoul]이 붙게된다.
또한 ZonedDateTime.now()의 인자로 ZoneId를 넘기게되면 해당 시간대로 변환된다.
LocalDateTime, ZonedDateTime간의 변환
ZonedDateTime -> LocalDateTime 변환
LocalDateTime seoulLocalDateTime = seoulZonedDateTime.toLocalDateTime();
LocalDateTime newYorkLocalDateTime = newYorkZonedDateTime.toLocalDateTime();
System.out.println("seoulLocalDateTime = " + seoulLocalDateTime);
System.out.println("newYorkLocalDateTime = " + newYorkLocalDateTime);
결과
seoulLocalDateTime = 2023-09-11T15:37:32.556348200
newYorkLocalDateTime = 2023-09-11T02:37:32.557345100
LocalDateTime -> ZonedDateTime 변환
예) 한국 시간 2023-09-07 09:15을 미국 뉴욕시간으로 변환
ZoneId seoulZoneId = ZoneId.of("Asia/Seoul");
LocalDateTime localDateTime1 = LocalDateTime.of(LocalDate.of(2023,9,7), LocalTime.of(9,15));
ZonedDateTime seoulZonedDateTime2 = localDateTime1.atZone(seoulZoneId); // 현재 ZoneId를 설정(seoul)
ZonedDateTime newYorkZonedDateTime2 = seoulZonedDateTime2.withZoneSameInstant(newYorkZoneId); // 뉴옥 ZoneId로 변경
System.out.println("seoulZonedDateTime2 = " + seoulZonedDateTime2);
System.out.println("newYorkZonedDateTime2 = " + newYorkZonedDateTime2);
결과
seoulZonedDateTime2 = 2023-09-07T09:15+09:00[Asia/Seoul]
newYorkZonedDateTime2 = 2023-09-06T20:15-04:00[America/New_York]
주의
LocalDateTime -> ZonedDateTime 변환시 atZone으로 현재 ZoneId를 설정 한후에 withZoneSameInstant를 사용하여 시간대를 변경하여야만 정상적으로 시간대가 변경된다.
atZone으로 Amerial/New_York으로 변경만 하면 아래와 같이 시간뒤에 +09:00[Amerial/New_York]만 붙게되니 조심하자
//주의
ZoneId newYorkZoneId = ZoneId.of("America/New_York");
LocalDateTime localDateTime3 = LocalDateTime.of(LocalDate.of(2023,9,7), LocalTime.of(9,15));
ZonedDateTime seoulZonedDateTime3 = localDateTime3.atZone(newYorkZoneId); // ZoneId만 "America/New_York"으로 설정한경우
System.out.println("localDateTime3 = " + localDateTime3);
System.out.println("seoulZonedDateTime3 = " + seoulZonedDateTime3);
결과
localDateTime3 = 2023-09-07T09:15
seoulZonedDateTime3 = 2023-09-07T09:15-04:00[America/New_York]
위와같이 실제 시간대가 변경된것이 아니라 localDateTime3 결과 뒤에 -04:00[America/New_York 만 붙게된다.
References
Java의 정석, 남궁 성 지음
'Java' 카테고리의 다른 글
| 날짜와 시간 - DateTimeFormatter (0) | 2023.09.11 |
|---|---|
| 날짜 계산 - TemporalAdjusters (0) | 2023.09.11 |
| 제네릭스 (0) | 2023.09.06 |
| Java Collection Set (0) | 2023.08.24 |
| Java Collection Map (0) | 2023.08.24 |