

가장 기본이 되는 날짜와 시간 클래스는 LocalDate, LocalTime, LocalDateTime이다.
Ex) 2013-11-21Ex) 08:20:30.213❗주의 : 모든 날짜 클래스는 불변으로 설계되어있다. 따라서 변경이 발생하는 경우 새로운 객체를 생성해서 반환해야한다.
isEquals()는 단순히 비교 대상이 시간적으로 같으면 true를 반환한다. 객체가 다르고 타임존이 달라도 시간적으로 같으면 true를 반환한다. equals()는 객체의 타입, 타임존 등등 내부 데이터의 모든 구성요소가 같아야 true를 반환한다.false가 된다.ZonedDateTime은 LocalDateTime에 시간대 정보인 ZoneId가 합쳐진 것이다.
public class ZonedDateTimeMain {
public static void main(String[] args) {
ZonedDateTime nowZdt = ZonedDateTime.now();
System.out.println("nowZdt = " + nowZdt);
LocalDateTime ldt = LocalDateTime.of(2030, 1, 1, 13, 30, 50);
ZonedDateTime zdt1 = ZonedDateTime.of(ldt, ZoneId.of("Asia/Seoul"));
System.out.println("zdt1 = " + zdt1);
ZonedDateTime zdt2 = ZonedDateTime.of(2030, 1, 1, 13, 30, 50, 0, ZoneId.of("Asia/Seoul"));
System.out.println("zdt2 = " + zdt2);
// withZoneSameInstant : 타임존 변경
ZonedDateTime utcZdt = zdt2.withZoneSameInstant(ZoneId.of("UTC"));
System.out.println("utcZdt = " + utcZdt);
}
}
OffsetDateTime은 LocalDateTime에 UTC 오프셋 정보인 ZoneOffset이 합쳐진 것이다.
public class OffsetDateTimeMain {
public static void main(String[] args) {
OffsetDateTime nowOdt = OffsetDateTime.now();
System.out.println("nowOdt = " + nowOdt);
LocalDateTime ldt = LocalDateTime.of(2030, 1, 1, 13, 30, 50);
System.out.println("ldt = " + ldt);
OffsetDateTime odt = OffsetDateTime.of(ldt, ZoneOffset.of("+01:00"));
System.out.println("odt = " + odt);
}
}
Instant는 UTC를 기준으로 하는 시간의 한 지점을 나타낸다. Instant 내부에는 초 데이터만 들어있다.(나노초 포함) 날짜와 시간을 계산하기에 부적합하다.
시간의 개념은 크게 2가지로 표현할 수 있다. (Period > Duration)

public class PeriodMain {
public static void main(String[] args) {
Period period = Period.ofDays(10);
System.out.println("period = " + period);
LocalDate currentDate = LocalDate.of(2030, 1, 1);
LocalDate plusDate = currentDate.plus(period);
System.out.println("currentDate = " + currentDate);
System.out.println("plusDate = " + plusDate);
LocalDate startDate = LocalDate.of(2023, 1, 1);
LocalDate endDate = LocalDate.of(2023, 4, 2);
Period between = Period.between(startDate, endDate);
System.out.println("기간 : " + between.getMonths() + "개월 " + between.getDays() + "일");
}
}
public class DurationMain {
public static void main(String[] args) {
Duration duration = Duration.ofMinutes(30);
System.out.println("duration = " + duration);
LocalTime localTime = LocalTime.of(1, 0);
System.out.println("localTime = " + localTime);
LocalTime plusTime = localTime.plus(duration);
System.out.println("plusTime = " + plusTime);
LocalTime start = LocalTime.of(9, 0);
LocalTime end = LocalTime.of(18, 0);
Duration between = Duration.between(start, end);
System.out.println("차이 : " + between.getSeconds() + "초");
System.out.println("근무 시간 : " + between.toHours() + "시간 " + between.toMinutesPart() + "분");
}
}

Temporal(TemporalAccessor 포함) 인터페이스를 구현한다.LocalDateTime, LocalDate, LocalTime, ZonedDateTime, OffsetDateTime, Instant 등이 있다.TemporalAmount 인터페이스를 구현한다.Duration, Period 등이 있다.TemporalAccessor의 하위 인터페이스로, 날짜와 시간을 조작하기 위한 기능을 제공한다.
public class GetTimeMain {
public static void main(String[] args) {
LocalDateTime dt = LocalDateTime.of(2030, 1, 1, 13, 30, 59);
System.out.println("YEAR : " + dt.get(ChronoField.YEAR));
System.out.println("MONTH_OF_YEAR : " + dt.get(ChronoField.MONTH_OF_YEAR));
System.out.println("DAY_OF_MONTH : " + dt.get(ChronoField.DAY_OF_MONTH));
System.out.println("HOUR_OF_DAY : " + dt.get(ChronoField.HOUR_OF_DAY));
System.out.println("MINUTE_OF_HOUR : " + dt.get(ChronoField.MINUTE_OF_HOUR));
System.out.println("SECOND_OF_MINUTE : " + dt.get(ChronoField.SECOND_OF_MINUTE));
System.out.println("편의 메서드 제공");
System.out.println("YEAR : " + dt.getYear());
System.out.println("MONTH_OF_YEAR : " + dt.getMonthValue());
System.out.println("DAY_OF_MONTH : " + dt.getDayOfMonth());
System.out.println("HOUR_OF_DAY : " + dt.getHour());
System.out.println("MINUTE_OF_HOUR : " + dt.getMinute());
System.out.println("SECOND_OF_MINUTE : " + dt.getSecond());
System.out.println("편의 메서드 없음");
System.out.println("MINUTE_OF_DAY = " + dt.get(ChronoField.MINUTE_OF_DAY));
System.out.println("SECOND_OF_DAY = " + dt.get(ChronoField.SECOND_OF_DAY));
}
}
public class ChangeTimePlusMain {
public static void main(String[] args) {
LocalDateTime dt = LocalDateTime.of(2018, 1, 1, 13, 30, 59);
System.out.println("dt = " + dt);
LocalDateTime plusDt1 = dt.plus(10, ChronoUnit.YEARS);
System.out.println("plusDt1 = " + plusDt1);
LocalDateTime plusDt2 = dt.plusYears(10);
System.out.println("plusDt2 = " + plusDt2);
Period period = Period.ofYears(10);
LocalDateTime plusDt3 = dt.plus(period);
System.out.println("plusDt3 = " + plusDt3);
}
}
public class ChangeTimeWithMain {
public static void main(String[] args) {
LocalDateTime dt = LocalDateTime.of(2018, 1, 1, 13, 30, 59);
System.out.println("dt = " + dt);
LocalDateTime changeDt1 = dt.with(ChronoField.YEAR, 2020);
System.out.println("changeDt1 = " + changeDt1);
LocalDateTime changeDt2 = dt.withYear(2020);
System.out.println("changeDt2 = " + changeDt2);
LocalDateTime with1 = dt.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
System.out.println("기준 날짜 : " + dt);
System.out.println("다음주 금요일 : " + with1);
LocalDateTime with2 = dt.with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY));
System.out.println("같은 달의 마지막 일요일 : " + with2);
}
}
public class FormattingMain {
public static void main(String[] args) {
LocalDate localDateTime = LocalDate.of(2024, 12, 31);
System.out.println("localDateTime = " + localDateTime);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일");
String format = localDateTime.format(formatter);
System.out.println("format = " + format);
String input = "2030년 01월 01일";
LocalDate parseDate = LocalDate.parse(input, formatter);
System.out.println("parseDate = " + parseDate);
}
}