Java

날짜와 시간 - LocalDateTime, ZonedDateTIme

hwanguu 2023. 9. 11. 15:51

날짜와 시간 비교 - 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