목표
- Java8부터 추가된 LocalDateTime, ZonedDateTime에 대한 기본이해 및 간단한 활용
날짜와 시간을 나타내는 자바 API는 여러가지가 있었지만 기능의 부족함으로 사용이 권장되지는 않았다.
(Calendar, Date 등)
하지만 자바8부터 등장한 java.time API는 이전 API의 결함을 상당부분 해결했고, 앞으로 제 역할을 할 것이라 기대된다.
Instant Class
Instant 클래스는 타임라인의 한 점을 나타낸다.
Immutable, thread-safe 하며 now()로 생성된 인스턴스를 리턴받을 수 있다.
equals(), compareTo() 처럼 비교를 위한 함수를 제공하므로 인스턴스끼리 시간비교가 가능하다.
@Test
public void Instant_Duration_기본() throws InterruptedException {
Instant start = Instant.now();
System.out.println("현재시각(인스턴스) : " + start); // 현재시각(인스턴스) : 2019-10-11T04:50:51.759Z
someComplicatedJob(); // 시간텀을 두기 위해서 임의의 JOB을 수행
// Instant는 한 점을 나타내므로 비교가 가능하다.
Instant end = Instant.now();
System.out.println("Instant 사이의 비교 - equals() : " + start.equals(end));
System.out.println("Instant 사이의 비교 - compareTo() : " + start.compareTo(end));
// 비교를 위해서 Duration 클래스를 사용할 수 있다.
// Duration : 두 Instant 사이에 있는 시간의 양, 불변 클래스
Duration timeElapsed = Duration.between(start, end);
System.out.println("JOB 수행에 걸린시간(밀리초) : " + timeElapsed.toMillis());
System.out.println("JOB 수행에 걸린시간(초) : " + timeElapsed.getSeconds());
System.out.println("JOB 수행시간이 마이너스인지 ? " + timeElapsed.isNegative());
}
|
cs |
Duration Class
시간차에 대한 작업을 위해 제공되는 클래스이다.
@Test
public void Duration_활용(){
Duration duration1 = Duration.ofHours(1); // 1시간 차이
Duration duration3 = Duration.ofHours(3); // 3시간 차이
// 두 Duration이 2배 이상 차이가 나는지 체크하는 코드
boolean overDoubleFaster1 = duration1.multipliedBy(2).minus(duration3).isNegative();
System.out.println("duration3이 duration1 보다 2배 더 빠른가 ? " + overDoubleFaster1);
boolean overDoubleFaster2 = duration1.toNanos() * 2 < duration3.toNanos();
System.out.println("duration3이 duration1 보다 2배 더 빠른가 ? " + overDoubleFaster2);
}
|
cs |
LocalDateTime
실제 사람이 사용하는 시간을 나타내는 API이다. Local(지역)이 접두어로 붙은 것에서 유추할 수 있듯이 여러 지역의 시간대(Time Zone) 정보는 포함하지 않는다.
KST나 UTC처럼 시간대를 지정하는 것이 정확한 표현이지만, 실제 활용에서 이러한 시간대는 잘 사용되지 않고 오히려 방해가 될 수 있으므로 만일 시간대를 필요로 하지 않는 작업이라면 LocalDateTime 사용을 고려한다.
LocalDate, LocalTime처럼 날짜, 시간에 특화된 API도 있지만 이 둘을 합쳐서 표현할 수 있는 LocalDateTime이 주로 사용된다.
@Test
public void LocalDate_LocalTime_LocalDateTime_기본(){
// 구역(Zone) 구분이 없는 지역날짜로 now()나 of()로 생성한다.
LocalDate nowDate = LocalDate.now();
LocalDate myBirthDay = LocalDate.of(1988, Month.MAY, 26); // '월'을 enum으로 줄 수도 있다.
System.out.println("현재날짜 : " + nowDate); // 2019-10-11
System.out.println("현재날짜 + 7일 : " + nowDate.plusDays(7L)); // 2019-10-18
System.out.println("현재날짜 + 7일 : " + nowDate.plusWeeks(1L)); // 2019-10-18
System.out.println("현재날짜 - 7일 : " + nowDate.minus(Period.ofDays(7))); // 2019-10-04
LocalTime nowtime = LocalTime.now();
System.out.println("현재시각 : " + nowtime); // 15:16:22.909
System.out.println("현재시각 + 1시간 : " + nowtime.plusHours(1L)); // 16:16:22.909
System.out.println("현재시각에서 시간만 3으로 변경 : " + nowtime.withHour(3)); // 03:16:22.909
LocalDateTime nowDateTime = LocalDateTime.now();
System.out.println("현재시각 : " + nowDateTime); // 2019-10-11T15:16:22.909
System.out.println("현재시각 + 1시간 : " + nowDateTime.plusHours(1L)); // 2019-10-11T16:16:22.909
System.out.println("현재시각에서 시간만 3 : " + nowDateTime.withHour(3)); // 2019-10-11T03:16:22.909
}
|
cs |
ZonedDateTime
LocalDateTime에서 시간대(Time Zone) 개념이 추가된 클래스로 기본적인 사용방법은 비슷하다.
다음과 같이 사용가능한 TimeZoneId를 출력해보면 많은 수가 있는것을 알 수 있다.
@Test
public void ZoneId(){
// 각 시간대는 America/New_York, Europe/Berlin 등 ID가 존재한다.
Set<String> availableZoneIds = ZoneId.getAvailableZoneIds(); // 이용할 수 있는 모든 시간대를 얻는다.
for(String str : availableZoneIds){
System.out.println(str); // Asia/Aden, America/Chicago, Europe/Luxembourg ...
}
}
|
cs |
많은 ZoneId 중에서도 아마 많이 사용할 시간대는 Asia/Seoul 과 UTC 일 것이다.
해당 타임존을 인자로하여 ZonedDateTime을 생성 후 출력해보면 인자로 준 시간대 정보가 같이 출력된다.
UTC의 경우 표준이니 별다른 내용이 없지만, Asia/Seoul의 경우는 표준 UTC 06시23분에 9시간이 더해져서 15시23분임을 알 수 있다.
LocalDateTime에 타임존을 추가하거나 ZonedDateTime에 타임존을 제거하면서 상호변환이 가능하다.
@Test
public void ZonedDateTime(){
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Asia/Seoul"));
System.out.println(now); // 2019-10-11T15:23:08.605+09:00[Asia/Seoul]
ZonedDateTime now2 = ZonedDateTime.now(ZoneId.of("UTC"));
System.out.println(now2); // 2019-10-11T06:23:08.605Z[UTC]
}
|
cs |
@Test
public void ZonedDateTime_to_LocalDateTime(){
ZonedDateTime nowUTC = ZonedDateTime.now(ZoneId.of("UTC"));
System.out.println(nowUTC);
LocalDateTime nowSeoul = nowUTC.withZoneSameInstant(ZoneId.of("Asia/Seoul")).toLocalDateTime();
System.out.println(nowSeoul);
ZonedDateTime nowSeoulZonedTime = nowSeoul.atZone(ZoneId.of("Asia/Seoul"));
System.out.println(nowSeoulZonedTime);
}
|
cs |
ZonedDateTime 인스턴스를 문자열(String)로 변경하거나 반대의 경우도 가능하다.
변환시 DateTimeFormatter를 인자로하여 원하는 패턴으로 변환한다.
@Test
public void formatting(){
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Asia/Seoul"));
String nowStr1 = now.format(DateTimeFormatter.ISO_DATE_TIME); // 2019-10-11T15:48:07.039+09:00[Asia/Seoul]
String nowStr2 = now.format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss z")); // 2019/10/11 15:48:07 KST
String nowStr3 = now.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL)); // 2019년 10월 11일 금요일 오후 3시 48분 07초 KST
String nowStr4 = now.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withLocale(Locale.US)); // Friday, October 11, 2019 3:48:07 PM KST
ZonedDateTime now1 = ZonedDateTime.parse(nowStr1);
ZonedDateTime now2 = ZonedDateTime.parse(nowStr2, DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss z"));
ZonedDateTime now3 = ZonedDateTime.parse(nowStr3, DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL));
ZonedDateTime now4 = ZonedDateTime.parse(nowStr4, DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withLocale(Locale.US));
System.out.println(now1);
System.out.println(now2);
System.out.println(now3);
System.out.println(now4);
}
|
cs |
EpochTime -> LocalDateTime 변환
시간을 표현하는 Long값인 EpochTime을 LocalDateTime으로 변환할 수 있다.
@Test
public void Epoch_to_LocalDateTime(){
// Epoch Time을 LocalDateTime으로 변경한다.
LocalDateTime now3 = LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()), ZoneId.of("Asia/Seoul"));
System.out.println(now3);
LocalDateTime now4 = LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()), ZoneId.of("UTC"));
System.out.println(now4);
}
|
cs |
읽어주셔서 감사합니다. 도움이 되셨다면 광고 클릭 부탁드립니다.
모두 힘내세요! : )
'개발 > JAVA' 카테고리의 다른 글
ExecutorService 사용법 (0) | 2020.12.01 |
---|---|
Comparator, Comparable 어떻게 사용할까? (0) | 2020.11.29 |
Collections를 이용한 정렬(sort method) 활용 (0) | 2017.05.09 |
BigDecimal & BigInteger (0) | 2017.04.18 |
Array 와 ArrayList 사이의 변환 (0) | 2017.03.28 |