10.3.1 time패키지
- time 패키지 내부의 클래스들은 항상 변경된 새로운 객체 반환
- 즉, 불변성(immutable)을 가짐
- 항상 새호운 객체가 반환되어서 동시에 여러 쓰레드가 같은 객체에 접근하는 멀티 쓰레드 환경에서 안전함
java.time : 날짜와 시간을 다루는데 필요한 핵심 클래스들을 제공
java.time.chrono : 표준(ISO)이 아닌 달력 시스템을 위한 클래스 제공
java.time.format : 날짜와 시간을 파싱하고, 형식화하기 위한 클래스들을 제공
java.time.temporal : 날짜와 시간의 필드(field)와 단위(unit)를 위한 클래스들을 제공
java.time.zone : 시간대(time-zone)와 관련된 클래스들을 제공
10.3.2 Period와 Duration
- Period : 날짜 - 날짜
- Duration : 시간 - 시간
- get()을 통해 필드 값을 가져옴
long year = pe.get(ChronoUnit.YEARS); //int getYears()
long month = pe.get(ChronoUnit.MONTHS); //int getMonths()
long day = pe.get(ChronoUnit.DASYS); //int getDays()
long sec = du.get(ChronoUnit.SECONDS); //long getSeconds()
int nano = du.get(ChronoUnit.NANOS); //int getNano()
10.3.3 now()와 of()
- java.time 클래스들의 객체 생성 방법
- now()
LocalDate date = LocalDate.now(); //2015-11-23
LocalTime time = LocalTime.now(); //21:54:01.875
LocalDateTime dateTime = LocalDateTime.now(); //2015-11-23T21:54:01.875
ZoneDateTime zone = ZoneDateTime.now(); //2015-11-23T21:54:01.875+09:00[Asia/Seoul]
- of()
LocalDate date = LocalDate.of(2015, 11, 23);
LocalTime time = LocalTime.of(23, 59, 59);
LocalDateTime dateTime = LocalDateTime.of(date, time);
ZonedDateTime zone = ZonedDateTime.of(dateTime, ZoneId.of("Asia/Seoul"));
10.3.4 TemporalUnit과 TemporalFeild
- TemporalUnit : 날짜와 시간의 단위를 저잘한 인터페이스. 구현체는 ChronoUnit[enum]
- TemporalField : 날짜와 시간의 필드 정의. 구현체는 ChronoField[enum]
AMPM_OF_DAY //오전, 오후
EPOCH_DAY //유닉스 시간부터 몇번째 날
ALIGNED_WEEK_OF_MONTH //그 달의 N번째 주(1~7일 1주, 8~14일 2주, ...)
ALIGNED_WEEK_OF_YEAR //그 해의 N번째 주(1~7일 1주, 8~14일 2주, ...)
INSTANT_SECONDS //년월일을 초단위로 환산(유닉스 시간)
OFFSET_SECONDS //UTC와 시차. ZoneOffset에서만 사용
10.3.5 LocalDate
int getYear()
int getMonthValue()
Month getMonth() //getMonth.getValue() = 12
int getDayOfMonth()
int getDayofYear()
DayOfWeek getDayOfWeek() //getDayOfWeek.getValue() = 5
int lengthOfMonth()
int lengthOfYear() //365. 윤년이면 366
boolean isLeapYear() //윤년여부 확인
10.3.6 LocalTime
int getHour()
int getMinute()
int getSecond()
int getNano()
10.3.7 필드의 값 변경
- with()
LocalDate withYear(int year) LocalTime withHour(int hour) LocalDate with(TemporalField field, long newValue);
- plus()
LocalDate plusYears(long yearsToAdd) LocalTime plusHours(long hourToAdd) LocalTime plus(TemporalAmount amountToAdd)
10.3.8 truncatedTo()
- LocalTime에 존재
- 지정된 값 보다 작은 단위의 필드를 0으로 만듦
LocalTime time = LocalTime.of(12, 34, 56); //12시 34분 56초
time = time.truncatedTo(ChronoUnit.HOURS); //12:00
10.3.9 날짜와 시간의 비교
- isEqual()
- 연표(chronology)가 다른 두 날짜 비교하기 위해 사용
- 오직 날짜만 비교
LocalDate kDate = LocalDate.of(1999, 12, 31);
JapanDate jDate = JapanDate.of(1999, 12, 31);
kDate.equals(jDate); //fasle. YEAR_OF_ERA가 다름
kDate.isEqual(jDate); //true
10.3.10 범위
- .range()
ChronoField.CLOCK_HOUR_OF_DAY.range(); //1-24
ChronoField.HOUR_OF_DAY.range(); //0-23
10.3.11 Instant
- 에포크 타임(EPOSCH TIME)부터 경과된 시간을 나노초 단위로 표현
- 단일 진법으로만 다루기 때문에 계산하기 쉽다.
//인스턴스 생성
Instant now1 = Instant.now();
Instant now2 = Instant.ofEpocyhSecond(now1.getEpochSecond());
Instant now3 = Instant.ofEpocyhSecond(now1.getEpochSecond(), now1.getNano());
//값 가져오기
long epochSec = now1.getEpochSecond();
int nano = now1.getNano();
- java.util.Date를 대체하기 위해 등장함
static Date from(Instant instant)
Instant toInstant()
/*
JDK 1.8 부터 Date 클래스에 Instant로 변환할 수 있는 메서드로 추가됨
*/
10.3.11 LocalDateTime
- LocalDate + LocalTime
LocalDate date = LocalDate.of(2015, 12, 31);
LocalTime time = LocalTime.of(12, 34, 56);
//date + time
LocalDateTime dt1 = LocalDateTime.of(date, time);
LocalDateTime dt2 = date.atTime(time);
LocalDateTime dt3 = time.atDate(date);
LocalDateTime dt4 = date.atTime(12, 34, 56);
LocalDateTime dt5 = time.atDate(LocalDate.of(2015, 12, 31));
LocalDateTime dt6 = date.atStartOfDay();
//LocalDateTime 인스턴스 생성
LocalDateTime dt7 = LocalDateTime.of(2015, 12, 31 ,12, 34, 56);
LocalDateTime dt8 = LocalDawteTime.now();
- 변환
LocalDateTime dt = LocalDateTime.of(2015, 12, 31 ,12, 34, 56);
LocalDate date = dt.toLocalDate();
LocalTime time = dt.toLocalTime();
10.3.12 ZonedDateTime
- ZoneId 클래스 사용
- 일광 절약시간(DST, Daylight Saving Time)을 자동으로 처리
ZoneId zid = ZoneId.of("Asia/Seoul");
ZonedDateTime zdt = dateTime.atZone(zid); //2015-11-23T21:54:01.875+09:00[Asia/Seoul]
- LocalDate의 atStartOfDay 사용
ZonedDateTime zdt = LocalDAte.now().atStartOfDay(zid); ////2015-11-23T21:54:01.875+09:00[Asia/Seoul]
- 특정 시간대의 시간
ZoneId zid = ZoneId.of("America/New_York");
ZonedDateTime nTime = ZoneDateTime.now().withZoneSameInstant(zid);
//2015-12-15T07:52:07.672-05:00[America/New_York]
10.3.13 ZoneOffset
- UTC로 부터 얼만큼 떨어져 있는지 표현
ZoneOffset krOffset1 = ZonedDateTime.now().getOffset();
//ZoneOffset krOffset2 = ZoneOffset.of("+9");
int krOffset1 = krOffset1.get(ChronoField.OFFSET_SECONDS); //32400
10.3.14 OffsetDateTime
- ZoneId가 아닌 ZoneOffset을 사용
- 다른 시간대에 존재하는 컴퓨터 통신에서 사용
ZoneOffset krOffset = ZonedDateTime.now().getOffset();
LocalDate date = LocalDate.of(2015, 11, 23);
LocalTime time = LocalTime.now(23, 59, 59);
OffsetDateTime odt = OffsetDateTime.of(date, time, krOffset);
10.3.15 ZonedDateTime의 변환
LocalDate toLocalDate()
LocalTime toLocalTime()
LocalDateTime toLocalDateTime()
OffsetDateTime toOffsetDateTime()
long toEpochSecond()
Instant toInstant()
//ZonedDateTime -> GregorianCalendar
GregorianCalendar from(ZonedDateTime zdt)
//GregorianCalendar -> ZonedDateTime
ZonedDateTime toZonedDateTime()
10.3.16 TemporalAdjusters
- 자주 쓰이는 날짜 계산 메서드가 정의되어 있음
firstDayOfNextYear() //다음해 첫 날
firstDayOfNextMonth() //다음다 첫 날
firstDayOfYear() //올 해의 첫 날
firstDayOfMonth() //이번 달의 첫 날
lastDayOfYear() //올 해의 마지막 날
lastDayOfMonth() //이번 달의 마지막 날
firstInMonth(DayOfWeek dayOfWeek) //이번달의 첫 번째 ?요일
lastInMonth(DayOfWeek dayOfWeek) //이번달의 마지막 ?요일
previous(DayOfWeek dayOfWeek) //지난 ?요일(당일 미포함)
previousOrSame(DayOfWeek dayOfWeek) //지난 ?요일(당일 포함)
next(DayOfWeek dayOfWeek) //다음 ?요일(당일 미포함)
nextOrSame(DayOfWeek dayOfWeek) //다음 ?요일(당일 포함)
dayOfWeekInMonth(int ordinal, DayOfWeek dayOfWeek) //이번 달의 n번째 ?요일
- 추상 메서드 하나만 정의되어 있음
@FunctionalInterface
public interface TemporalAdjuster{
Temporal adjustInto(Temporal temporal);
}
/*
상속을 받아 직접 사용해도 되지만, adjustInto는 내부에서만 사용할 용도로 작성되었가 때문에
구현체에 있는 with() 사용하는 것을 추천
*/
LocalDate today = new LocalDate.now();
today.with(fisrtDayOfNextMonth()) //2016-01-01. 다음달의 첫 날
today.with(firstDayOfMonth()) //2015-12-01. 이번 달의 첫 날
10.3.17 between()
- 두 날짜의 차이
LocalDate d1 = LocalDate.of(2014, 1, 1);
LocalDate d2 = LocalDate.of(2015, 11, 31);
Period pe = Period.between(d1, d1);
LocalTime t1 = LocalTime.of(00, 00, 00);
LocalTime t2 = LocalTime.of(12, 34, 56);
Duration du = Duration.between(t1, t2);
/*
-get-
long year = pe.get(ChronoUnit.YEARS); //int getYears()
long month = pe.get(ChronoUnit.MONTHS); //int getMonths()
long day = pe.get(ChronoUnit.DASYS); //int getDays()
long sec = du.get(ChronoUnit.SECONDS); //long getSeconds()
int nano = du.get(ChronoUnit.NANOS); //int getNano()
Period와 달리 Duration은 getHours나 getMinutes()같은 메서드가 존재하지 않음.
하지만, LocalTime을 이용하면 가능
*/
LocalTime t = LocalTime.of(0,0).plusSeconds(du.getSeconds());
int hour = t.getHour();
int min = t.getMinute();
int sec = t.getSecond();
int nano = t.getNano();
10.3.18 Period와 Duration
- Period : 날짜 - 날짜
- Duration : 시간 - 시간
//of
Period pe = Period.of(1, 12, 31); //1년 12개월 31일
Duration du = Duration.of(60, ChronoUnit.SECONDS); //60초
Duration du2 = Duration.ofSeconds(60); //60초
//with
pe = pe.withYears(2); //1년에서 2년으로 변경
du = du.withSeconds(120); //60초에서 120초로 변경
//사칙연산
pe = pe.minusYears(1).multipliedBy(2); //1년을 빼고, 2배를 곱함
du = du.plusHours(1). dividedBy(60); //1시간을 더하고 60으로 나눈다
//기타
boolean same = Period.between(date1, date2).isZero();
boolean negative = Duration.between(time1, time2).isNegative();
- 다른 단위로 변환
//Period
long toTotalMonths() //년월일을 월단위로 변환(일 단위는 무시)
//Duration
long toDays() //일단위로 변환
long toHours() //시간 단위로 변환
long toMonutes() //분 단위로 변환
long toMiilis() //천분의 일초 단위로 변환
long toNanos() //나노초 단위로 변환
10.3.19 파싱과 포맷
- 대부분 DateTimeFormatter를 사용
LocalDate date = LocalDate.of(2016, 1, 2);
String y1 = DateTimeFormatter.ISO_LOCAL_DATE.format(date); //2016-01-02
String y2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE);
- 로케일에 종속된 형식화
DateTimeFormatter fo = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
String sh = formatter.format(LocalDAte.now());
10.3.20 출력형식 직접 정의
- ofPattern()으로 원하는 출력형식 직접 작성가능
ZonedDateTime z = ZonedDateTime.now();
DateTimeFormatter fo = DateTimeFormatter.ofPattern("yyy/MM/dd");
z.format(fo);
10.3.21 문자열을 날짜와 시간으로 파싱
- parse()
static LocalDateTime parse(CharSequence text)
static LocalDateTime parse(CharSequence text, DateTimeFormatter formatter)
LocalDate date1 = LocalDate.parse("2016-12-11", DateTimeFormatter.ISO_LOCAL_DATE);
DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyy/MM/dd HH:mm:ss");
LocalDate date1 = LocalDate.parse("2016-12-11 23:59:59", pattern);
'자바의 정석 정리' 카테고리의 다른 글
자바의 정석 - 13.2 쓰레드의 구현과 실행 (0) | 2022.08.29 |
---|---|
자바의 정석 - 13.1 프로세스와 쓰레드 (0) | 2022.08.29 |
자바의 정석 - 10.2 형식화 클래스 (0) | 2022.07.07 |
자바의 정석 - 10.1 날짜와 시간 (0) | 2022.07.07 |
자바의 정석 - 8.3 사용자정의 예외 (0) | 2022.06.17 |