java8에서 새로 나온 날짜와 시간을 나타내는 api이다. 기존에 사용했던 Date, Calendar, SimpleDateFormat은 여러 불편함이 존재한다. 예를 들어 이름이 명확하지 않다.
Date의 경우 날짜 뿐만 아니라 time stamp도 나타낼 수 있다. 또 한 Date.getTIme()은 일상적으로 사용하는 시간이 아닌 1970년 1월 1일 0시 0분 0초를 기준으로 현재시간을 뺀 값을 밀리세컨드 단위로 보여준다. 또 한 객체가 mutable하기 때문에 Date.setTime()을 통해 시간을 바꿀 수 있다. 따라서 thread-safe하지 않다.
GregorianCalendar의 경우 type-safe하지 않다는 문제가 발생한다. GregorianCalendar는 연도, 월, 날짜를 인자로 넘겨서 인스턴스를 생성할 수 있는데 달이 0부터 시작한다. 따라서 임의의 수를 직접 넘기는 것이 아닌 enum을 사용해 넘겨야 한다. 또 한 연도, 달, 일을 int로 받기 때문에 음수가 들어올 가능성 또한 존재한다.

이런 문제를 해결하기 위해 Joda-Time을 사용했었고 java8에서 표준으로 들어오게 되었다.
java8에서 추가된 Date, Time은 크게 기계용 시간(machine time), 인류용 시간(human time)으로 나눌 수 있다. 기계용 시간은 EPOCK(1970-1-1, 0시0분0초)부터 밀리세컨드단위로, human time은 실생활에서 사용하는 단위로 나온다.
API 사용 예제
Instant는 기계용 시간을 계산할때 사용한다.
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
 | 
 public static void main(String[] args) { 
    //machine time사용 
    Instant machineTime = Instant.now(); 
    System.out.println(machineTime); // 기준시 UTC, GMT를 기준으로 시간이 나온다. 
    System.out.println(machineTime.atZone(ZoneId.of("UTC"))); 
    //자신이 속한 시간대를 가져와서 
    ZoneId zone = ZoneId.systemDefault(); 
    System.out.println(zone); 
    //GMT 기준 시간이 아닌 자신이 속한 시간대의 시간으로 구한다. 
    ZonedDateTime zonedDateTime = machineTime.atZone(zone); 
    System.out.println(zonedDateTime); 
} 
 | 
cs | 
LocalDateTIme은 현재 시스템이 위치한 time zone을 기준으로 human time을 사용한다.
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
 | 
 public static void main(String[] args) { 
    //human time 사용         
    //현재 시스템이 있는 local zone의 시간이 찍힌다 
    //즉, 서버가 다른 local zone에 있으면 그 나라의 시간을 가져온다. 
    LocalDateTime humanTime = LocalDateTime.now(); 
    System.out.println(humanTime); 
    //시간과 날짜를 지정해서 만들 수 도 있다. 
    LocalDateTime birthDay = 
            LocalDateTime.of(1999, Month.MARCH, 28, 0, 0, 0); 
    System.out.println(birthDay); 
} 
 | 
cs | 
Time zone을 지정해서 특정 time zone의 현재 시간은 다음과 같이 구할 수 있다.
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
 | 
 public static void main(String[] args) { 
    //zone id를 사용해 특정 time zone의 현재 시간을 알아낸다. 
    ZonedDateTime nowInKorea = ZonedDateTime.now(ZoneId.of("Asia/Seoul")); 
    System.out.println(nowInKorea); 
    //다음과 같은 방식을 사용하면 위와 같은 값을 구할 수 있다. 
    Instant nowInstant = Instant.now(); 
    ZonedDateTime zonedDateTime = nowInstant.atZone(ZoneId.of("Asia/Seoul")); 
    System.out.println(zonedDateTime); 
} 
 | 
cs | 
시간을 비교해 기간 정하기
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
 | 
  public static void main(String[] args) { 
    LocalDate today = LocalDate.now(); 
    LocalDate thisYearBirthDay = LocalDate.of(2021, Month.MARCH, 28); 
    //human time을 비교 
    Period period = Period.between(today, thisYearBirthDay); 
    System.out.println(period.getDays()); 
    Period util = today.until(thisYearBirthDay); 
    System.out.println(util.get(ChronoUnit.DAYS)); 
    //machine time을 비교 
    Instant now = Instant.now(); 
    Instant plus = now.plus(10, ChronoUnit.SECONDS); 
    Duration between = Duration.between(now, plus); 
    System.out.println(between.getSeconds()); 
} 
 | 
cs | 
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
 | 
 public static void main(String[] args) { 
    LocalDateTime now = LocalDateTime.now(); 
    DateTimeFormatter MMddyyyy = DateTimeFormatter.ofPattern("MM/dd/yyy"); 
    System.out.println(now.format(MMddyyyy));//11/22/2021 
    LocalDate parse = LocalDate.parse("07/15/1982", MMddyyyy); 
    System.out.println(parse);//1982-07-15 
} 
 | 
cs | 

java8에서 추가된 Time, Date관련 API는 이전 API와 호환된다.
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
 | 
 public static void main(String[] args) { 
    // Date -> Instant 
    Date date = new Date(); 
    Instant instant = date.toInstant(); 
    // Instant -> Date 
    Date newDate = Date.from(instant); 
    System.out.println(newDate); 
    //GregorianCalendar -> ZonedDateTime 
    GregorianCalendar gregorianCalendar = new GregorianCalendar(); 
    ZonedDateTime dateTime = gregorianCalendar.toInstant() 
            .atZone(ZoneId.systemDefault()); 
    System.out.println(dateTime); 
    //GregorianCalendar -> LocalDateTime 
    LocalDateTime localDateTime = gregorianCalendar.toInstant() 
            .atZone(ZoneId.systemDefault()) 
            .toLocalDateTime(); 
    System.out.println(localDateTime); 
    // ZonedDateTime -> GregorianCalendar 
    ZonedDateTime zonedDateTime = gregorianCalendar.toInstant() 
            .atZone(ZoneId.systemDefault()); 
    GregorianCalendar from = GregorianCalendar.from(zonedDateTime); 
    System.out.println(from); 
    // ZoneId -> TimeZone 
    ZoneId zoneId = TimeZone.getTimeZone("PST") 
            .toZoneId(); 
    System.out.println(zoneId); 
    // TimeZone -> ZoneId 
    TimeZone timeZone = TimeZone.getTimeZone(zoneId); 
    System.out.println(timeZone); 
} 
 | 
cs | 
'java > java8' 카테고리의 다른 글
| Concurrent programming (0) | 2021.11.22 | 
|---|---|
| optional (0) | 2021.11.22 | 
| stream (0) | 2021.11.21 | 
| interface의 default method와 static method (0) | 2021.11.20 | 
| 함수형 인터페이스와 람다 표현식 (0) | 2021.11.20 |