- [Java8] Date와 Time API 목차
프로젝트를 진행하면서 시간과 날짜를 계산하는 일이 굉장히 많았다.
하지만 그 과정에서 헷갈린 부분을 정리하고 확실한 개념을 짚고 넘어가보고자 글을 정리한다.
| Date & Time 소개
java8에 새로운 날짜와 시간 API가 생긴 이유
- 그전까지 사용하던 java.util.Date 클래스는 mutable(변하기 쉬운) 하기 때문에 thread safe 하지 않았다.
- 클래스 이름이 명확하지 않다 ( Date인데 시간까지 다루는 점에 대해 의아했음 )
- 버그가 발생하는 일이 많았다 ( type의 안정성이 없고 월 같은 경우 0부터 시작하는게 이해가 안돼..)
- 날짜 시간 처리가 복잡한 application에서는 보통 Joda Time을 쓰곤 했다.
하지만 !!
java8 에서 제공하는 Date-Time API JSR-310 스펙의 구현체를 제공한다.
https://jcp.org/en/jsr/detail?id=310
주요 API
1. 기계용 시간(machine time)과 인류용 시간으로 나눌 수 있다.
2. 기계용 시간은 EPOCK(1970년 1월1일 0시0분0초)부터 현재까지의 TimeStamp를 표현한다.
3. 인류용 시간은 우리가 흔히 사용하는 연,월,일,시,분,초 등을 표현한다.
4. TimeStamp는 Instant를 사용한다.
5. 특정 날짜(LocalDate), 시간(LocalTime), 일시(LocalDateTime)을 사용할 수 있다.
6. 기간을 표현할 때는 Duration(시간 기반)과 Period(날짜 기반)를 사용할 수 있다.
7. DateTimeFormatter를 사용해서 일시를 특정한 문자열로 포매팅할 수 있다.
| instant 활용
예시 ( 시간을 재거나 method 실행 시간을 측정할 때 사용 (기계용) )
Instant instant = Instant.now();
System.out.println(instant);
ZoneId zone = ZoneId.systemDefault();
System.out.println(zone);
ZonedDateTime zonedDateTime = instant.atZone(zone);
System.out.println(zonedDateTime);
| LocalDateTime
인간용
서버에 배포가 되면 서버가 실행되는 국가에 따라서 시간이 auto setting 되기 때문에 주의한다.
method
- of(int Month, int,int,int,int)
-> of를 사용하여 년,월,일,시를 설정할 수 있다.
- now()
->현재 시스템 Zone에 해당하는 (로컬) 일시를 return한다.
- ZonedDateTime.of(int Month,int,int,int,int,ZoneId)
->특정 Zone의 특정 일시를 return한다.
| 기간을 표현하는 방법 (Period 와 Duration)
- Period / Duration.between()
->인간용 비교
Period between = Period.between(today,birthDay);
System.out.println(between.get(ChronoUnit.DAYS));
Period 생일을 활용한 예시
LocalDate today = LocalDate.now();
LocalDate myBirthDay = LocalDate.of(2020, Month.AUGUST, 23); //생일 setting
//case 1 between()을 활용한 예시
Period period = Period.between(today, myBirthDay);
System.out.println(period.getDays());
//case 2 until()을 활용한 예시
Period until = today.until(myBirthDay);
System.out.println(until.getDays());
->Period 객체를 생성 후 between() OR until() & getDays() 를 활용하여 날짜가 얼마나 남은지 계산할 수 있다.
- Duration
->기계용 비교
//기계용 ( 메서드 시간 측정 등 )
Instant now2 = Instant.now();
//현재 초 부터 10초 차이가 나도록 더해줌
Instant plus = now2.plus(10,ChronoUnit.SECONDS);
Duration between = Duration.between(now2, plus);
System.out.println(between.getSeconds());
//결과
10
| 문자열 입력 OR 출력
//format
LocalDateTime now3 = LocalDateTime.now();
DateTimeFormatter MMddyyyy = DateTimeFormatter.ofPattern("yyyy/MM/dd");
System.out.println(now3.format(MMddyyyy));
//결과
2020/08/01
custom하게 pattern을 설정해줄 경우 LocalDateTime 으로 ofPattern() 메서드에 출력하고자 하는 형식을 지정해주고
LocalDateTime 객체의 format() 메서드를 호출하면 된다.
참고 Doc
https://codeblog.jonskeet.uk/2017/04/23/all-about-java-util-date/
All about java.util.Date
This post is an attempt to reduce the number of times I need to explain things in Stack Overflow comments. You may well be reading it via a link from Stack Overflow – I intend to refer to thi…
codeblog.jonskeet.uk
https://docs.oracle.com/javase/tutorial/datetime/overview/index.html
Lesson: Date-Time Overview (The Java™ Tutorials > Date Time)
The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available. See JDK Release Notes for information about new fe
docs.oracle.com
https://docs.oracle.com/javase/tutorial/datetime/iso/overview.html
| 사용자 입력 값(문자열) 파싱
- parse
사용자가 원하는 형태인 날짜 형식으로 값을 뽑아내고 싶다면 parse 를 사용하여 파싱한다.
//parse
//사용자가 문자열로 입력 값을 입력하면 -> 원하는 형식을 지정해주면 파싱되어 출력해준다.
DateTimeFormatter MMddyyyy2 = DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDate parse = LocalDate.parse("1993/08/23",MMddyyyy2);
System.out.println(parse);
//결과
1993-08-23 // 문자열을 날짜 형식으로 출력한다
| Date & Instant Type Change 호환성 레거시 API 지원
//Date와의 호환성
Date date = new Date(); //date 객체 생성
Instant instant3 = date.toInstant(); //date객체를 Instant로 전환
Date newDate = Date.from(instant3); // Instant객체를 from() 메서드를 활용하여 Date객체로 전환
-> Date 객체와 Instant 객체는 서로 호환되어 타입을 바꿀 수 있다.
또한
-
GregorianCalendar와 Date 타입의 인스턴스를 Instant나 ZonedDateTime으로 변환 가능.
-
java.util.TimeZone에서 java.time.ZoneId로 상호 변환 가능하다.
ZoneId newZoneAPI = TimeZone.getTimeZone("PST").toZoneId();
TimeZone legacyZoneAPI = TimeZone.getTimeZone(newZoneAPI);
'Java > Java8' 카테고리의 다른 글
스트림과 병렬 처리 (0) | 2021.05.29 |
---|---|
[java] and(), or(), negate() 디폴트 메소드와 isEqual()정적 메소드 (0) | 2020.10.28 |
[Java8]LocalDateTime이란? (0) | 2020.08.22 |