6. 날짜와 시간
6.1 날짜와 시간 라이브러리가 필요한 이유
- 날짜와 시간 차이 계산
- 윤년 계산
- 일광 절약 시간 변환
- 타임존 계산
6.2 자바 날짜와 시간 라이브러리

LocalDate, LocalTime, LocalDateTime
- LocalDate : 날짜만 표현할 때 사용한다.
- LocalTime : 시간만을 표현할 때 사용한다.
- LocalDateTime : LocalDate와 LocalTime을 합한 개념이다.
ZonedDateTime, OffsetDateTime
- ZonedDateTime : 타임존을 포함한 날짜와 시간을 표현할 때 사용한다.
- 예) 2013-11-21T08:20:30.213+9:00[Asia/Seoul]
- Asia/Seoul 은 타임존이라 한다. 이 타임존을 알면 오프셋과 일광 절약 시간제에 대한 정보를 알 수 있다.
- OffsetDateTime : 시간대를 고려한 날짜와 시간을 표현할 때 사용한다. 여기에는 타임존은 없고, UTC로 부터의 시간대 차이인 고정된 오프셋만 포함한다.
- 예) 2013-11-21T08:20:30.213+9:00
Year, Month, YearMonth, MonthDay
년, 월, 년월, 달일을 각각 다룰 때 사용한다.
DayofWeek 와 같이 월, 화, 수, 목, 금, 토, 일을 나타내는 클래스도 있다.
Instant
Instant 는 UTC를 기준으로 하는, 시간의 한 지점을 나타낸다. Instant 는 날짜와 시간을 나노초 정밀도로 표현하며, 1970년 1월 1일 0시 0분 0초(UTC)를 기준으로 경과한 시간으로 계산된다.
Instant 내부에는 초 데이터만 들어있다.(나노초 포함)
Period, Duration
시간의 개념은 크게 2가지로 표현할 수 있다.
- 특정 시점의 시간(시각)
- 시간의 간격(기간)
Period, Duration 은 시간의 간격(기간)을 표현하는데 사용된다.
Period
두 날짜 사이의 간격을 년, 월, 일 단위로 나타낸다.
Duration
두 시간 사이의 간견을 시, 분, 초(나노초) 단위로 나타낸다
6.3 기본 날짜와 시간 - LocalDateTime
- LocalDate : 날짜만 표현할 때 사용한다.
- LocalTime : 시간만을 표현할 때 사용한다.
- LocalDateTime : LocalDate와 LocalTime을 합한 개념이다.
앞에 Local 이 붙는 이유는 세계 시간대를 고려하지 않아서 타임존이 적용되지 않기 때문이다.
LocalDate
LocalDate nowDate = LocalDate.now();
LocalDate ofDate = LocalDate.of(2013, 11, 21);
System.out.println("오늘 날짜 = " + nowDate);
System.out.println("지정 날짜 = " + ofDate);
// 계산(불변)
LocalDate plusDays = ofDate.plusDays(10);
System.out.println("지정 날짜+10d = " + plusDays);
실행 결과
오늘 날짜 = 2024-02-09
지정 날짜 = 2013-11-21
지정 날짜+10d = 2013-12-01
- now() : 현재 시간을 기준으로 생성한다.
- of(...) : 특정 날짜를 기준으로 생성한다.
- plusDays() : 특정 일을 더한다. 다양한 plusXxx() 메서드가 존재한다.
LocalTime
LocalTime nowTime = LocalTime.now();
LocalTime ofTime = LocalTime.of(9, 10, 30);
System.out.println("현재 시간 = " + nowTime);
System.out.println("지정 시간 = " + ofTime);
// 계산(불변)
LocalTime ofTimePlus = ofTime.plusSeconds(30);
System.out.println("지정 시간+30s = " + ofTimePlus);
실행 결과
현재 시간 = 11:52:51.219602
지정 시간 = 09:10:30
지정 시간+30s = 09:11:00
- now() : 현재 시간을 기준으로 생성한다.
- of(...) : 특정 시간을 기준으로 생성한다. 시, 분, 초, 나노초를 입력할 수 있다.
- plusSeconds() : 특정 초를 더한다. 다양한 plusXxx() 메서드가 존재한다.
주의! - 불변
모든 날짜 클래스는 불변이다. 따라서 변경이 발생하는 경우 새로운 객체를 생성해서 반환하므로 반환값을 꼭 받아야 한다.
LocalDateTime
LocalDateTime 은 LocalDate 와 LocalTime 을 내부에 가지고 날짜와 시간을 모두 표현한다.
LocalDateTime nowDt = LocalDateTime.now();
LocalDateTime ofDt = LocalDateTime.of(2016, 8, 16, 8, 10, 1);
System.out.println("현재 날짜시간 = " + nowDt);
System.out.println("지정 날짜시간 = " + ofDt);
// 날짜와 시간 분리
LocalDate localDate = ofDt.toLocalDate();
LocalTime localTime = ofDt.toLocalTime();
System.out.println("localDate = " + localDate);
System.out.println("localTime = " + localTime);
// 날짜와 시간 합체
LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
System.out.println("localDateTime = " + localDateTime);
// 계산(불변)
LocalDateTime ofDtPlus = ofDt.plusDays(1000);
System.out.println("지정 날짜시간+1000d = " + ofDtPlus);
LocalDateTime ofDtPlus1Year = ofDt.plusYears(1);
System.out.println("지정 날짜시간+1년 = " + ofDtPlus1Year);
// 비교
System.out.println("현재 날짜시간이 지정 날짜시간보다 이전인가? " + nowDt.isBefore(ofDt));
System.out.println("현재 날짜시간이 지정 날짜시간보다 이후인가? " + nowDt.isAfter(ofDt));
System.out.println("현재 날짜시간과 지정 날짜시간이 같은가? " + nowDt.isEqual(ofDt));
실행 결과
현재 날짜시간 = 2024-02-09T11:54:54.389163
지정 날짜시간 = 2016-08-16T08:10:01
localDate = 2016-08-16
localTime = 08:10:01
localDateTime = 2016-08-16T08:10:01
지정 날짜시간+1000d = 2019-05-13T08:10:01
지정 날짜시간+1년 = 2017-08-16T08:10:01
현재 날짜시간이 지정 날짜시간보다 이전인가? false
현재 날짜시간이 지정 날짜시간보다 이후인가? true
현재 날짜시간과 지정 날짜시간이 같은가? false
생성
- now() : 현재 날짜와 시간을 기준으로 생성한다.
- of(...) : 특정 날짜와 시간을 기준으로 생성한다.
분리
날짜(LocalDate)와 시간(LocalTime) 을 toXxx() 메서드로 분리할 수 있다.
합체
- LocalDateTime.of(LocalDate, LocalTime) : 날짜와 시간을 사용해서 LocalDateTime을 만든다.
비교
- isBefore() : 다른 날짜시간과 비교한다. 현재 날짜와 시간이 이전이라면 true 를 반환한다.
- isAfter() : 다른 날짜시간과 비교한다. 현재 날짜와 시간이 이후이라면 true 를 반환한다.
- isEqual() : 다른 날짜시간과 시간적으로 동일한지 비교한다. 시간이 같으면 true 를 반환한다.
- isEqual() vs equals()
- isEqual() 는 단순히 비교 대상이 시간적으로 같으면 true 를 반환한다. 객체가 다르고, 타임존이 달라도 시간적으로 같으면 true 를 반환한다.
- 예) 서울의 9시와 UTC의 0시는 시간적으로 같다. 이 둘을 비교하면 true 를 반환한다.
- equals() 객체의 타입, 타임존 등등 내부 데이터의 모든 구성요소가 같아야 true 를 반환한다.
- 예) 서울의 9시와 UTC의 0시는 시간적으로 같다. 이 둘을 비교하면 타임존의 데이터가 다르기 때문에 false 를 반환한다.
6.4 타임존 - ZonedDateTime
"Asia/Seoul" 같은 타임존 안에는 일광 절약 시간제에 대한 정보와 UTC+9:00 와 같은 UTC로 부터 시간 차이인 오프셋 정보를 모두 포함하고 있다.
타임존 목록 예시
- Europe/London
- GMT
- UTC
- US/Arizona -07:00
- America/New_York -05:00
- Asia/Seoul +09:00
- Asia/Dubai +04:00
- Asia/Istanbul +03:00
- Asia/Shanghai +08:00
- Europe/Paris +01:00
- Europe/Berlin +01:00
ZoneId
자바는 타임존을 ZoneId 클래스로 제공한다.
for (String availableZoneId : ZoneId.getAvailableZoneIds()) {
ZoneId zoneId = ZoneId.of(availableZoneId);
System.out.println(zoneId + " | " + zoneId.getRules());
}
ZoneId zoneId = ZoneId.systemDefault();
System.out.println("ZoneId.systemDefault = " + zoneId);
ZoneId seoulZoneId = ZoneId.of("Asia/Seoul");
System.out.println("seoulZoneId = " + seoulZoneId);
실행 결과
Europe/London | ZoneRules[currentStandardOffset=Z]
UTC | ZoneRules[currentStandardOffset=Z]
GMT | ZoneRules[currentStandardOffset=Z]
Asia/Seoul | ZoneRules[currentStandardOffset=+09:00]
Asia/Dubai | ZoneRules[currentStandardOffset=+04:00]
US/Arizona | ZoneRules[currentStandardOffset=-07:00]
Asia/Istanbul | ZoneRules[currentStandardOffset=+03:00]
Asia/Shanghai | ZoneRules[currentStandardOffset=+08:00]
...
Europe/Paris | ZoneRules[currentStandardOffset=+01:00]
ZoneId.systemDefault = Asia/Seoul
seoulZoneId = Asia/Seoul
생성
- ZoneId.systemDefault() : 시스템이 사용하는 기본 ZoneId 를 반환한다.
- 각 PC 환경마다 다른 결과가 나올 수 있다.
- ZoneId.of() : 타임존을 직접 제공해서 ZoneId를 반환한다.
ZonedDateTime
ZonedDateTime 은 LocalDateTime 에 시간대 정보인 ZoneId 가 합쳐진 것이다.
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);
ZonedDateTime utcZdt = zdt2.withZoneSameInstant(ZoneId.of("UTC"));
System.out.println("utcZdt = " + utcZdt);
실행 결과
nowZdt = 2024-02-09T12:02:13.457712+09:00[Asia/Seoul]
zdt1 = 2030-01-01T13:30:50+09:00[Asia/Seoul]
zdt2 = 2030-01-01T13:30:50+09:00[Asia/Seoul]
utcZdt = 2030-01-01T04:30:50Z[UTC]
타임존 변경
withZoneSameInstant(ZoneId) : 타임존을 변경한다. 타임존에 맞추어 시간도 함께 변경된다. 이 메서드를 사용하면 지금 다른 나라는 몇 시인지 확인할 수 있다.
OffsetDateTime
OffsetDateTime 은 LocalDateTime 에 UTC 오프셋 정보인 ZoneOffset 이 합쳐진 것이다.
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);
실행 결과
nowOdt = 2024-02-13T15:03:36.422230+09:00
ldt = 2030-01-01T13:30:50
odt = 2030-01-01T13:30:50+01:00
6.5 기계 중심의 시간 - Instant
Instant 는 UTC를 기준으로 하는, 시간의 한 지점을 나타낸다. Instant 는 날짜와 시간을 나노초 정밀도로 표현하며, 1970년 1월 1일 0시 0분 0초(UTC)를 기준으로 경과한 시간으로 계산된다.
Instant 특징
- 장점
- 시간대 독립성 : Instant는 UTC를 기준으로 하므로, 시간대에 영향을 받지 않는다. 이는 전 세계 어디서나 동일한 시점을 가리키는데 유용한다.
- 고정된 기준점 : 모든 Instant 는 1970년 1월 1일 UTC를 기준으로 하기 때문에, 시간 계산 및 비교가 명확하고 일관된다.
- 단점
- 사용자 친화적이지 않음 : Instant 는 기계적인 시간 처리에는 적합하지만, 사람이 읽고 이해하기에는 직관적이지 않다.
- 시간대 정보 부재 : Instant 에는 시간대 정보가 포함되어 있지 않아, 특정 지역의 날짜와 시간으로 변환하려면 추가적인 작업이 필요하다.
6.6 기간, 시간의 간격 - Duration, Period
Period, Duration 은 시간의 간격(기간)을 표현하는데 사용된다.
Period
//생성
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);
System.out.println("더한 날짜: " + 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() + "일");
실행 결과
period = P10D
현재 날짜: 2030-01-01
더한 날짜: 2030-01-11
기간: 3개월 1일
Duration
//생성
Duration duration = Duration.ofMinutes(30);
System.out.println("duration = " + duration);
LocalTime lt = LocalTime.of(1, 0);
System.out.println("기준 시간 = " + lt);
//계산에 사용
LocalTime plusTime = lt.plus(duration);
System.out.println("더한 시간 = " + plusTime);
//시간 차이
LocalTime start = LocalTime.of(9, 0);
LocalTime end = LocalTime.of(10, 0);
Duration between = Duration.between(start, end);
System.out.println("차이: " + between.getSeconds() + "초");
System.out.println("근무 시간: " + between.toHours() + "시간 " + between.toMinutesPart() + "분");
실행 결과
duration = PT30M
기준 시간 = 01:00
더한 시간 = 01:30
차이: 3600초
근무 시간: 1시간 0분
6.7 날짜와 시간의 핵심 인터페이스
날짜와 시간은 특정 시점의 시간(시각)과 시간의 간격(기간)으로 나눌 수 있다.

TemporalAccessor 인터페이스
- 날짜와 시간을 읽기 위한 기본 인터페이스
- 이 인터페이스는 특정 시점의 날짜와 시간 정보를 읽을 수 있는 최소환의 기능을 제공한다.
Temporal 인터페이스
- TemporalAccessor 의 하위 인터페이스로, 날짜와 시간을 조작(추가, 빼기 등)하기 위한 기능을 제공한다. 이를 통해 날짜와 시간을 변경하거나 조작할 수 있다.
TemporalAmount 인터페이스
- 시간의 간격(시간의 양, 기간)을 나타내며, 날짜와 시간 객체에 적용하여 그 객체를 조정할 수 있다. 예를 들어, 특정 날짜에 일정 기간을 더하거나 빼는 데 사용된다.
시간의 단위와 시간 필드
- TemporalUnit : 시간의 단위
- TemporalField : 시간 필드

시간의 단위 - TemporalUnit, ChronoUnit
- TemporalUnit 인터페이스는 날짜와 시간을 측정하는 단위를 나타내며, 주로 사용되는 구현체는 java.time.temporal.ChronoUint 열거형으로 구현되어 있다.
- ChronoUnit 은 다양한 시간 단위를 제공한다.
ChronoUnit[] values = ChronoUnit.values();
for (ChronoUnit value : values) {
System.out.println("value = " + value);
}
System.out.println("HOURS = " + ChronoUnit.HOURS);
System.out.println("HOURS.duration = " + ChronoUnit.HOURS.getDuration().getSeconds());
System.out.println("DAYS = " + ChronoUnit.DAYS);
System.out.println("DAYS.duration = " + ChronoUnit.DAYS.getDuration().getSeconds());
//차이 구하기
LocalTime lt1 = LocalTime.of(1, 10, 0);
LocalTime lt2 = LocalTime.of(1, 20, 0);
long secondsBetween = ChronoUnit.SECONDS.between(lt1, lt2);
System.out.println("secondsBetween = " + secondsBetween);
long minutesBetween = ChronoUnit.MINUTES.between(lt1, lt2);
System.out.println("minutesBetween = " + minutesBetween);
실행 결과
value = Nanos
value = Micros
value = Millis
value = Seconds
value = Minutes
value = Hours
value = HalfDays
value = Days
value = Weeks
value = Months
value = Years
value = Decades
value = Centuries
value = Millennia
value = Eras
value = Forever
HOURS = Hours
HOURS.duration = 3600
DAYS = Days
DAYS.duration = 86400
secondsBetween = 600
minutesBetween = 10
시간 필드 - TemporalField, ChronoField
ChronoField 는 날짜 및 시간을 나타내느 데 사용되는 열거형이다. 이 열거형은 다양한 필드를 통해 날짜와 시간의 특정 부분을 나타낸다. 여기에는 연도, 월, 일, 시간, 분 등이 포함된다.
ChronoField[] values = ChronoField.values();
for (ChronoField value : values) {
System.out.println(value + ", range = " + value.range());
}
System.out.println("MONTH_OF_YEAR.range() = " + ChronoField.MONTH_OF_YEAR.range());
System.out.println("DAY_OF_MONTH.range() = " + ChronoField.DAY_OF_MONTH.range());
실행 결과
NanoOfSecond, range = 0 - 999999999
NanoOfDay, range = 0 - 86399999999999
MicroOfSecond, range = 0 - 999999
MicroOfDay, range = 0 - 86399999999
MilliOfSecond, range = 0 - 999
MilliOfDay, range = 0 - 86399999
SecondOfMinute, range = 0 - 59
SecondOfDay, range = 0 - 86399
MinuteOfHour, range = 0 - 59
MinuteOfDay, range = 0 - 1439
HourOfAmPm, range = 0 - 11
ClockHourOfAmPm, range = 1 - 12
HourOfDay, range = 0 - 23
ClockHourOfDay, range = 1 - 24
AmPmOfDay, range = 0 - 1
DayOfWeek, range = 1 - 7
AlignedDayOfWeekInMonth, range = 1 - 7
AlignedDayOfWeekInYear, range = 1 - 7
DayOfMonth, range = 1 - 28/31
DayOfYear, range = 1 - 365/366
EpochDay, range = -365243219162 - 365241780471
AlignedWeekOfMonth, range = 1 - 4/5
AlignedWeekOfYear, range = 1 - 53
MonthOfYear, range = 1 - 12
ProlepticMonth, range = -11999999988 - 11999999999
YearOfEra, range = 1 - 999999999/1000000000
Year, range = -999999999 - 999999999
Era, range = 0 - 1
InstantSeconds, range = -9223372036854775808 - 9223372036854775807
OffsetSeconds, range = -64800 - 64800
MONTH_OF_YEAR.range() = 1 - 12
DAY_OF_MONTH.range() = 1 - 28/31
6.8 날짜와 시간 조회하고 조작하기
날짜와 시간 조회하기
날짜와 시간을 조회하려면 날짜와 시간 항목 중에 어떤 필드를 조회할지 선택해야 한다. 이때 날짜와 시간의 필드를 뜻하는 ChronoField 가 사용된다.
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));
실행 결과
YEAR = 2030
MONTH_OF_YEAR = 1
DAY_OF_MONTH = 1
HOUR_OF_DAY = 13
MINUTE_OF_HOUR = 30
SECOND_OF_MINUTE = 59
편의 메서드 사용
YEAR = 2030
MONTH_OF_YEAR = 1
DAY_OF_MONTH = 1
HOUR_OF_DAY = 13
MINUTE_OF_HOUR = 30
SECOND_OF_MINUTE = 59
편의 메서드에 없음
MINUTE_OF_DAY = 810
SECOND_OF_DAY = 48659
TemporalAccessor.get(TemporalField field)
- LocalDateTime 을 포함한 특정 시점의 시간을 제공하는 클래스는 모두 TemporalAccessor 인터페이스를 구현한다.
- TemporalAccessor 는 특정 시점의 시간을 조회하는 기능을 제공한다.
- get(TemporalField field) 을 호출할 때 어떤 날짜와 시간 필드를 조회할 지 TemporalField 의 구현체인 ChronoField 를 인수로 전달하면 된다.
날짜와 시간 조작하기
날짜와 시간을 조작하려면 어떤 시간 단위(Unit)를 변경할 지 선택해야 한다. 이때 날짜와 시간의 단위를 뜻하는 ChronoUnit 이 사용된다.
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);
실행 결과
dt = 2018-01-01T13:30:59
plusDt1 = 2028-01-01T13:30:59
plusDt2 = 2028-01-01T13:30:59
plusDt3 = 2028-01-01T13:30:59
Temporal plus(long amountToAdd, TemporalUnit unit)
- LocalDateTime 을 포함한 특정 시점의 시간을 제공하는 클래스는 모두 Temporal 인터페이스를 구현한다.
- Temporal 은 특정 시점의 시간을 조작하는 기능을 제공한다.
- plus(long amountToAdd, TemporalUnit unit) 를 호출할 때 더하기 할 숫자와 시간의 단위(Unit)를 전달하면 된다. 이때 TemporalUnit 의 구현인 ChronoUnit 을 인수로 전달하면 된다.
- 불변이므로 반환 값을 받아야 한다.
- 참고로 minus() 도 존재한다.
with()
LocalDateTime dt = LocalDateTime.of(2018, 1, 1, 13, 30, 59);
System.out.println("dt = " + dt);
LocalDateTime changedDt1 = dt.with(ChronoField.YEAR, 2020);
System.out.println("changedDt1 = " + changedDt1);
LocalDateTime changedDt2 = dt.withYear(2020);
System.out.println("changedDt2 = " + changedDt2);
//TemporalAdjuster 사용
//다음주 금요일
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);
실행 결과
dt = 2018-01-01T13:30:59
changedDt1 = 2020-01-01T13:30:59
changedDt2 = 2020-01-01T13:30:59
기준 날짜: 2018-01-01T13:30:59
다음 금요일: 2018-01-05T13:30:59
같은 달의 마지막 일요일 = 2018-01-28T13:30:59
Temporal with(TemporalField field, long newValue)
- Temporal.with() 를 사용하면 날짜와 시간의 특정 필드의 값만 변경할 수 있다.
- 불변이므로 반환 값을 받아야 한다.
TemporalAdjuster 사용
- with() 는 아주 단순한 날짜만 변경할 수 있다. 다음 주 금요일, 이번 달의 마지막 일요일 같은 복잡한 날짜를 계산하고 싶다면 TemporalAdjuster 를 사용하면 된다.
6.9 날짜와 시간 문자열 파싱과 포맷팅
- 포맷팅 : 날짜와 시간 데이터를 원하는 포맷의 문자열로 변경하는 것 Date -> String
- 파싱 : 문자열을 날짜와 시간 데이터로 변경하는 것 String -> Date
// 포맷팅: 날짜를 문자로
LocalDate date = LocalDate.of(2024, 12, 31);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일");
String formattedDate = date.format(formatter);
System.out.println("날짜와 시간 포맷팅: " + formattedDate);
// 파싱: 문자를 날짜로
String input = "2030년 01월 01일";
LocalDate parsedDate = LocalDate.parse(input, formatter);
System.out.println("문자열 파싱 날짜와 시간: " + parsedDate);
실행 결과
현재 날짜와 시간 포맷팅: 2024년 12월 31일
문자열 파싱 날짜와 시간: 2030-01-01
LocalDate 과 같은 날짜 객체를 원하는 형태의 문자로 변경하려면 DateTimeFormatter 를 사용하면 된다. 여기에 ofPattern() 으로 원하는 포맷을 지정하면 된다. 여기서는 yyyy년 MM월 dd일 포맷을 지정했다.
문자열을 날짜와 시간으로 파싱
LocalDate.parse(input, formatter)
// 포맷팅: 날짜와 시간을 문자로
LocalDateTime now = LocalDateTime.of(2024, 12, 31, 13, 30, 59);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = now.format(formatter);
System.out.println("날짜와 시간 포맷팅: " + formattedDateTime);
// 파싱: 문자를 날짜와 시간으로
String dateTimeString = "2030-01-01 11:30:00";
LocalDateTime parsedDateTime = LocalDateTime.parse(dateTimeString, formatter);
System.out.println("문자열 파싱 날짜와 시간: " + parsedDateTime);
실행 결과
현재 날짜와 시간 포맷팅: 2024-12-31 13:30:59
문자열 파싱 날짜와 시간: 2030-01-01T11:30
6.10 날짜와 시간의 주요 메서드 정리





