날짜와 시간
지난 글의 Date와 Calendar 클래스에 이어 time 패키지에 대해 알아봅시다.
Java.time패키지
Java.time패키지는 jdk1.8부터 Date, Calendar 클래스를 보완하기 위해 추가되었습니다. time 패키지의 클래스들은 Calendar클래스와 달리 불변의 특성을 가지고 있어 멀티스레드 환경에서도 안전합니다.
핵심 클래스와 인터페이스
인터페이스 | 구현클래스 | 내용 |
Temproal, TemporalAccesser, TemporalAdjuster |
LocalDate | 날짜 |
LocalTime | 시간 | |
LocalDateTime | 날짜, 시간 | |
ZonedDateTime | 날짜, 시간, 시간대 |
클래스 | 내용 |
TemporalAdjusters | 자주쓰는 날짜 계산 메서드들 정의 |
인터페이스 | 구현클래스 | 내용 |
TemporalAmount | Period | 두 날짜간의 차이 |
Duration | 두 시간간의 차이 |
인터페이스 | 구현클래스 | 내용 |
TemporalUnit | ChronoUnit | 날짜와 시간의 단위 (열거형) |
TemporalField | ChronoField | 년, 월, 일 등 날짜와 시간의 필드를 정의 (열거형) |
객체 생성 방법
static 메서드 now()와 of()를 사용하여 객체를 생성합니다.
- now() : 현재 날짜와 시간을 저장하는 객체를 생성합니다.
- of() : 해당 필드의 값을 순서대로 지정하는 객체를 생성합니다.
LocalDate today = LocalDate.now(); //오늘의 날짜
LocalTime now = LocalTime.now(); //현재 시간
static LocalDate of(int year, Month month, int dayOfMonth)
static LocalDate of(int year, int month, int dayOfMonth)
static LocalTime of(int hour, int min)
static LocalTime of(int hour, int min, int sec)
static LocalTime of(int hour, int min, int sec, int nanoOfSecond)
LocalDate, LocalTime
필드 값 가져오기 - get(), get###()
LocalDate형, LocalTime형 인스턴스 local
자료형마다 사용할 수 있는 Field는 다름
local.get(ChronoField.ERA) 시대
local.get(ChronoField.YEAR)
local.get(ChronoField.YEAR_OF_ERA) 년
local.get(ChronoField.MONTH_OF_YEAR) (1~12)
local.get(ChronoField.AMPM_OF_DAY) 오전/오후
local.get(ChronoField.HOUR_OF_DAY) 시간 (0~23)
local.get(ChronoField.CLOCK_HOUR_OF_DAY) 시간 (1~24)
local.get(ChronoField.HOUR_OF_AMPM) 시간 (0~11)
local.get(ChronoField.CLOCK_HOUR_OF_AMPM) 시간 (1~12)
local.get(ChronoField.MINUTE_OF_HOUR) 분
local.get(ChronoField.SECOND_OF_MINUTE) 초
local.get(ChronoField.MILLI_OF_SECOND) 천분의 1초 (0~999)
local.get(ChronoField.MICRO_OF_SECOND) 백만분의 1초
local.get(ChronoField.NANO_OF_SECOND) 10억분의 1초
local.get(ChronoField.DAY_OF_YEAR) 이 해의 몇 일
local.get(ChronoField.EPOCH_DAY) EPOCH (1970.1.1)부터 몇번째 날
local.get(ChronoField.MINUTE_OF_DAY) 그 날의 몇 번째 분 (시간을 분으로 환산)
local.get(ChronoField.SECOND_OF_DAY) 그 날의 몇 번째 초 (시간을 초로 환산)
local.get(ChronoField.MILLI_OF_DAY) 그 날의 몇 번째 분 (시간을 분으로 환산)
local.get(ChronoField.MICRO_OF_DAY) 그 날의 몇 번째 분 (시간을 분으로 환산)
local.get(ChronoField.NANO_OF_DAY) 그 날의 몇 번째 분 (시간을 분으로 환산)
local.get(ChronoField.MINUTE_OF_DAY) 그 날의 몇 번째 분 (시간을 분으로 환산)
local.get(ChronoField.ALIGNED_WEEK_OF_MONTH) 그 달의 몇 째 주(1~7일 1주...)
local.get(ChronoField.ALIGNED_WEEK_OF_YEAR) 그 해의 몇 째 주
local.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH) 요일 (그달의 1일을 월요일로 간주하여 계산)
local.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR) 요일 (그 해의 1월 1일을 월요일로 간주하여 계산)
local.get(ChronoField.INSTANT_SECONDS) 년월일을 초단위로 환산 Instant에만 사용가능
local.get(ChronoField.OFFSET_SECONDS) UTC와의 시차 ZoneOffset에만 사용가능
local.get(CHronoField.PROLEPTIC_MONTH) 년월을 월단위로 환산 (2015년 11월 = 2015*12+11)
//LocalDate
getYear() 년도
getMonthValue() 월 (12)
getMonth() 월 (DECEMBER)
getDayOfMonth() 일
getDayOfYear() 같은 해의 1월 1일부터 몇번째 일 (365)
getDayOfWeek() 요일
lengthOfMonth() 같은 달의 총 일수
lengthOfYear() 같은 해의 총 일수(365) 윤년이면 366
isLeepYear() 윤년여부확인
//LocalTime
getHour() 시(23)
getMinute() 분(59)
getSecond() 초(59)
getNano() 나노초
필드 값 변경하기 - with(), plus(), minus(), truncatedTo()
with()
LocalDate withYear(int year)
LocalDate withMonth(int month)
LocalDate withDayOfMonth(int dayOfMonth)
LocalDate withDayOfYear(int dayOfYear)
LocalTime withHour(int hour)
LocalTime withMinute(int minute)
LocalTime withSecond(int second)
LocalTime withNano(int nanoOfSecond)
LocalDate with(TemporalField field, long newValue)
//필드를 변경하는 메서드는 항상 새로운 객체를 생성해서 반환
plus(), minus()
LocalDate plusYears(long yearsToAdd)
LocalDate plusMonths(long monthsToAdd)
LocalDate plusDays(long daysToAdd)
LocalDate plusWeeks(long weeksToAdd)
LocalTime plusHours(long hoursToAdd)
LocalTime plusMinutes(long minutesToAdd)
LocalTime plusSeconds(long secondsToAdd)
LocalTime plusNanos(long nanosToAdd)
// minus도 plus와 같음
LocalTime의 truncatedTo()
//지정된 것보다 작은 단위의 필드를 0으로 만듦
12시 34분 56초 -> truncatedTo(ChronoUnit.HOURS) -> 12:00
날짜와 시간의 비교 - compareTo(), isAfter(), isBefore(), isEqual()
compareTo()
int result = date1.compareTo(date2);
//같으면 0, date1이 이전이면 -1, 이후면 1
isAfter(), isBefore()
boolean isAfter (ChronoLocalDate other) // other보다 이후이면 true 반환
boolean isBefore (ChronoLocalDate other) // other보다 이전이면 true 반환
equals(), isEqual()
boolean equals (ChronoLocalDate other) // 필드의 모든 값을 비교
boolean isEqual (ChronoLocalDate other) // 날짜만 비교
LocalDateTime과 ZonedDateTime
객체생성
LocalDateTime
LocalDate date = LocalDate.of(2023,1,3);
LocalTime time = LocalTime.of(12,34,56);
LocalDateTime dt = 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(2023,1,3));
LocalDateTime dt6 = date.atStartOfDay(); // time을 0, 0, 0 으로 설정
LocalDateTime dt7 = LocalDateTime.of(2023, 1, 3, 12, 34, 56);
LocalDateTime dt8 = LocalDateTime.now();
- of()와 now()를 사용하거나 LocalDate와 LocalTime을 합치는 등 다양한 방법으로 객체를 생성할 수 있습니다.
ZonedDateTime
ZoneId zid = ZoneId.of("Asia/Seoul");
ZoneDateTime zdt = dateTime.atZone(zid);
ZonedDateTime sdt = LocalDate.now().atStartOfDay(zid);
ZonedDateTime time = ZonedDateTime.now().withZoneSameInstant(zid);
- ZoneId클래스를 사용하는 방법 : 일광 절약 시간을 (DST, Daylight Saving Time) 자동으로 처리해 주는 장점이 있습니다.
- LocalDate의 atStartOfDay() 메서드를 사용하는 방법 : 0시 0분 0초로 설정합니다.
- ZoneDateTime의 withZoneSameInstant() 메서드를 사용하는 방법 : 특정 지역의 시간으로 설정합니다.
LocalDateTime의 변환
// LocalDateTime 형 인스턴스 dt
LocalDate date = dt.toLocalDate(); // LocalDateTime -> LocalDate
LocalTime time = dt.toLocalTime(); // LocalDateTime -> LocalTime
TemporalAdjusters
자주 쓰일만한 날짜 계산 메서드들이 정의되어 있습니다.
firstDayOfNextYear() //다음 해의 첫 날
firstDayOfNextMonth() //다음 달의 첫 날
firstDayOfYear() //올 해의 첫 날
firstDayOfMonth() //이번 달의 첫 날
lastDayOfYear() //올 해의 마지막 날
lastDayOfMonth() //이번 달의 마지막 날
firstInMonth(DayOfWeek dayOfWeek) //이번 달의 첫번째 ? 요일
lastInMonth(DayOfWeek dayOfWeek) //이번 달의 마지막 ? 요일
previous(DayOfWeek dayOfWeek) //지난 ?요일(당일 미포함)
previousOrSame(DayOfWeek dayOfWeek) //지난 ?요일(당일 포함)
next(DayOfWeek dayOfWeek) //다음 ?요일(당일 미포함)
nextOrSamte(DayOfWeek dayOfWeek) //다음 ?요일(당일 포함)
dayOfWeekInMonth(int ordinal, DayOfWeek dayOfWeek) //이번 달의 n번째 ?요일
Period, Duration
Period : 날짜 차이 계산
Duration : 시간 차이 계산
Period pe = Period.between(date1, date2); // static메서드, 사이의 기간
Period pe = today.until(myBirthDay); // instance메서드, ~까지의 기간
long dday = totay.until(myBirthDay, ChronoUnit.Days) // 년,월,일이 아니라 일로만 구하고 싶을 때
long sec = LocalTime.now().until(endTime, ChronoUnit.SECONDS);
Duration du = Duration.between(time1, time2); // Duration을 반환하는 until()은 없음
//특정 필드의 값을 얻을 때 geT(), get###() 메서드를 사용
long year = pe.get(ChronoUnit.YEARS) // int getYears()
long month = pe.get(ChronoUnit.MONTHS) // int getMonths()
long day = pe.get(ChronoUnit.DAYS) // int getDays()
long sec = du.get(ChronoUnit.SECONDS) // long getSeconds()
int nano = du.get(ChronoUnit.NANOS) // int getNanos()
// Duration에는 getHours(), getMinutes()메서드가 없습니다.
// 따라서 초를 변형해서 사용하거나
// Duration을 LocalTime으로 변환한 다음에 get메서드를 사용해줍니다.
LocalTime tmpTime = LocalTime.of(0,0).plusSeconds(du.getSeconds());
of(), with()
// of() : 해당 필드의 값을 순서대로 지정
Period
of(), ofYears(), ofMonths(), ofWeeks(), ofDays()
Duration
of(), ofDays(), ofHours(), ofMinutes(), ofSeconds()
// with() : 특정 필드값 변경
pe.withYears(3);
du.withSeconds(500);
다른 단위로 변환
Period
toTotalMonths() // 년월일을 월단위로 변환 (일단위 무시)
Duration
toDays() // 일단위로
toHours() //시간단위로
toMinutes() //분단위로
toMillis() //천분의 일초 단위로
toNanos() //나노초 단위로
길고 긴 날짜 시간 백과사전이 끝났습니다. 아직 배열을 기억하고 계시겠죠? 다음 글에서는 배열과 비슷하지만 더 자주 쓰이는 컬렉션 프레임워크에 대해 알아보겠습니다. 감사합니다.
'개발언어 > Java : 자바' 카테고리의 다른 글
자바 쉽게 배우기 15 - 컬렉션 프레임워크(2) : Set, Queue (0) | 2023.02.08 |
---|---|
자바 쉽게 배우기 14 - 컬렉션 프레임워크(1) : List (0) | 2023.02.03 |
자바 쉽게 배우기 12 - 날짜와 시간(1) (0) | 2023.01.27 |
자바 쉽게 배우기 11 - 예외 처리 (0) | 2023.01.23 |
자바 쉽게 배우기 10 - 다양한 클래스와 인터페이스 (0) | 2023.01.21 |