목표 

  • 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

목표

  • UTC, GMT, Epoch Time에 대한 이해

UTC, GMT

그리니치 평균시(Greenwich Mean Time, GMT)는 런던을 기점, 웰링턴을 종점으로 하는 협정 세계시의 빠른시간이다.

세계협정시(Coordinated Universal Time, UTC)와 혼용해서 쓰이므로 같다고 생각하면 된다.

(세부적으로는 차이가 있지만 사용하는데 있어서는 같다고 이해하자.)

 

Epoch Time

1970년 01월 01일 자정(UTC/GMT) 이후로 초단위로 지난시간을 나타낸다.

Epoch Time과 같은 의미의 단어로 Unix Epoch, Unix Time, POSIX Time, Unix Timestamp 등이 있다.


보통 프로그래밍시에 시간 측정을 위해서 사용되는 System.currentTimeMillis()가 Epoch Time을 반환하며, 반환값은 밀리세컨드 단위로 반환되므로 1000을 나눠줘야 초 단위가 된다.

long epoch = System.currentTimeMillis()/1000;

참고 사이트 : https://www.epochconverter.com/

'개발 > 기타' 카테고리의 다른 글

LastModified 헤더를 이용한 파일변경 체크  (0) 2020.12.06
Maven 기본  (0) 2019.11.12
Ajax에 관하여  (0) 2018.12.13
META-INF 디렉터리에 대하여  (1) 2018.04.12
TCP/IP  (0) 2017.08.01

+ Recent posts