기본 날짜와 시간 - LocalDateTime
가장 기본이 되는 날짜와 시간 클래스는 `LocalDate` , `LocalTime` , `LocalDateTime` 이다.
**LocalDate**: 날짜만 표현할 때 사용한다. 년, 월, 일을 다룬다. 예) `2013-11-21`
**LocalTime**: 시간만을 표현할 때 사용한다. 시, 분, 초를 다룬다. 예) `08:20:30.213`
초는 밀리초, 나노초 단위도 포함할 수 있다.
**LocalDateTime**: `LocalDate` 와 `LocalTime` 을 합한 개념이다. 예) `2013-11-21T08:20:30.213`
코드로 나타내는게 훨씬 이해도 잘 되고
쓰기에 유용할거에요!!
1)LocalDate
package time;
import java.time.LocalDate;
public class LocalDateMain {
public static void main(String[] args) {
LocalDate nowDate = LocalDate.now();
LocalDate ofDate = LocalDate.of(2014,5,8);
System.out.println("현재 날짜 : "+nowDate);
System.out.println("지정 날짜 : "+ofDate);
LocalDate plusDays = ofDate.plusDays(12);
System.out.println("날짜는 불변이다 --> 새로운객체를 만들어반환해야함");
System.out.println("지정날짜 + 12 : "+plusDays);}}
출력
현재 날짜 : 2025-01-01
지정 날짜 : 2014-05-08
날짜는 불변이다 --> 새로운객체를 만들어반환해야함
지정날짜 + 12 : 2014-05-20
생성**
`now()` : 현재 시간을 기준으로 생성한다.
`of(...)` : 특정 날짜를 기준으로 생성한다. 년, 월, 일을 입력할 수 있다.
**계산**
`plusDays()` : 특정 일을 더한다. 다양한 `plusXxx()` 메서드가 존재한다.
(불변이므로 꼭 객체를 반환해야함 !! )
2)LocalTime
package time;
import java.time.LocalTime;
public class LocalTimeMain {
public static void main(String[] args) {
LocalTime nowTime = LocalTime.now();
LocalTime ofTime = LocalTime.of(10,20,40);
System.out.println("현재시간 : "+nowTime);
System.out.println("지정시간 : "+ofTime);
//계산
LocalTime plusHM = ofTime.plusHours(4).plusMinutes(30);
System.out.println("시간역시 불변 !! 객체생성해 반환");
System.out.println("지정시간 + 4시간30분"+ " : "+plusHM);}}
출력
현재시간 : 14:17:46.201435
지정시간 : 10:20:40
시간역시 불변 !! 객체생성해 반환
지정시간 + 4시간30분 : 14:50:40
**생성**
`now()` : 현재 시간을 기준으로 생성한다.
`of(...)` : 특정 시간을 기준으로 생성한다. 시, 분, 초, 나노초를 입력할 수 있다.
**계산**
`plusHours()` : 특정 시간을 더한다. 다양한 `plusXxx()` 메서드가 존재한다.
3)LocalDateTime
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class LocalDateTimeMain {
public static void main(String[] args) {
LocalDateTime nowDt = LocalDateTime.now();
LocalDateTime ofDt = LocalDateTime.of(2023,11,20, 15,30,40);
System.out.println("현재날짜 + 시간 "+nowDt);
System.out.println("지정날짜 + 시간 "+ofDt);
System.out.println("\n날짜 시간 분리 (toLocalDate , toLocaltime) ");
LocalDate nowDate = nowDt.toLocalDate();
LocalTime nowTime = nowDt.toLocalTime();
System.out.println("현재날짜 : "+nowDate);
System.out.println("현재시간 : "+nowTime);
System.out.println("\n 날짜 시간 합체");
LocalDateTime nowDt2 = LocalDateTime.of(nowDate, nowTime);
System.out.println("현재 날짜 + 시간2 : "+nowDt2);
//계산 (불변)
System.out.println("\n 계산은 불변 (객체 반환 필수)");
LocalDateTime plus = ofDt.plusYears(1).plusDays(8).plusHours(7);
System.out.println("(지정날짜+시간) + 1년 8일 7시간 " +plus);
System.out.println("\n 비교");
System.out.println("현재날짜가 지정날짜보다 이전인가? : "+ nowDt.isBefore(ofDt));
System.out.println("현재날짜가 지정날짜보다 이후인가? : "+ nowDt.isAfter(ofDt));
System.out.println("현재날짜와 지정날짜가 같은가? "+nowDt.isEqual(ofDt));
}
}
출력
현재날짜 + 시간 2025-01-01T14:19:37.871357
지정날짜 + 시간 2023-11-20T15:30:40
날짜 시간 분리 (toLocalDate , toLocaltime)
현재날짜 : 2025-01-01
현재시간 : 14:19:37.871357
날짜 시간 합체
현재 날짜 + 시간2 : 2025-01-01T14:19:37.871357
계산은 불변 (객체 반환 필수)
(지정날짜+시간) + 1년 8일 7시간 2024-11-28T22:30:40
비교
현재날짜가 지정날짜보다 이전인가? : false
현재날짜가 지정날짜보다 이후인가? : true
현재날짜와 지정날짜가 같은가? false
생성**
`now()` : 현재 날짜와 시간을 기준으로 생성한다.
`of(...)` : 특정 날짜와 시간을 기준으로 생성한다.
**분리**
날짜(`LocalDate` )와 시간(`LocalTime` )을 `toXxx()` 메서드로 분리할 수 있다.\
**합체**
`LocalDateTime.of(localDate, localTime)`
날짜와 시간을 사용해서 `LocalDateTime` 을 만든다.
**계산**
`plusXxx()` : 특정 날짜와 시간을 더한다. 다양한 `plusXxx()` 메서드가 존재한다.
**비교**
**isBefore()**: 다른 날짜시간과 비교한다. 현재 날짜와 시간이 이전이라면 `true` 를 반환한다.
**isAfter()**: 다른 날짜시간과 비교한다. 현재 날짜와 시간이 이후라면 `true` 를 반환한다.
**isEqual()**: 다른 날짜시간과 시간적으로 동일한지 비교한다. 시간이 같으면 `true` 를 반환한다.
4) 타임존 - ZonedDateTime
*타임존 목록 예시**
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클래스로 제공
import java.time.ZoneId;
public class ZoneIdMain {
public static void main(String[] args) {
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);}}
출력
Asia/Aden | ZoneRules[currentStandardOffset=+03:00]
America/Cuiaba | ZoneRules[currentStandardOffset=-04:00]
Etc/GMT+9 | ZoneRules[currentStandardOffset=-09:00]
Etc/GMT+8 | ZoneRules[currentStandardOffset=-08:00]
Africa/Nairobi | ZoneRules[currentStandardOffset=+03:00]
America/Marigot | ZoneRules[currentStandardOffset=-04:00]
Asia/Aqtau | ZoneRules[currentStandardOffset=+05:00]
Pacific/Kwajalein | ZoneRules[currentStandardOffset=+12:00]
America/El_Salvador | ZoneRules[currentStandardOffset=-06:00]
Asia/Pontianak | ZoneRules[currentStandardOffset=+07:00]
Africa/Cairo | ZoneRules[currentStandardOffset=+02:00]
Pacific/Pago_Pago | ZoneRules[currentStandardOffset=-11:00]
Africa/Mbabane | ZoneRules[currentStandardOffset=+02:00]
Asia/Kuching | ZoneRules[currentStandardOffset=+08:00]
.......
ZoneId.systemDefault = Asia/Seoul
seoulZoneId = Asia/Seoul
**생성**
`ZoneId.systemDefault()` : 시스템이 사용하는 기본 `ZoneId` 를 반환한다.
각 PC 환경 마다 다른 결과가 나올 수 있다.
`ZoneId.of()` : 타임존을 직접 제공해서 `ZoneId` 를 반환한다.
ZonedDateTime
LocalDateTime + ZoneId
**ZonedDateTime**: 시간대를 고려한 날짜와 시간을 표현할 때 사용한다.
여기에는 시간대를 표현하는 타임존이 포함된다.
예) `2013-11-21T08:20:30.213+9:00[Asia/Seoul]``+9:00` 은 UTC(협정 세계시)로 부터의 시간대 차이이다.
오프셋이라 한다. 한국은 UTC보다 +9:00 시간이다.
`Asia/Seoul` 은 타임존이라고 한다. 이 타임존을 알면 오프셋도 알 수 있다.
+9:00 같은 오프셋 정보도 타임존에 포함된다.
추가로 `ZoneId` 를 통해 타임존을 알면 일광 절약 시간제에 대한 정보도 알 수 있다. 따라서 일광 절약 시간제가
적용된다.
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class ZonedDateTimeMain {
public static void main(String[] args) {
ZonedDateTime nowZDt = ZonedDateTime.now();
System.out.println(nowZDt);
LocalDateTime ldt = LocalDateTime.of(2021,11,20,15,10,40);
ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.of("Asia/Seoul"));
System.out.println("zdt : "+zdt);
ZonedDateTime zdt2 = zdt.withZoneSameInstant(ZoneId.of("UTC"));
System.out.println("zdt2 : "+zdt2);
}}
**생성**
`now()` : 현재 날짜와 시간을 기준으로 생성한다. 이때 `ZoneId` 는 현재 시스템을 따른다.
(`ZoneId.systemDefault()` )`of(...)` : 특정 날짜와 시간을 기준으로 생성한다. `ZoneId` 를 추가해야 한다.
`LocalDateTime` 에 `ZoneId` 를 추가해서 생성할 수 있다.
**타임존 변경**
`withZoneSameInstant(ZoneId)` : 타임존을 변경한다. 타임존에 맞추어 시간도 함께 변경된다. 이 메서드
를 사용하면 지금 다른 나라는 몇 시 인지 확인일 수 있다.
예를 들어서 서울이 지금 9시라면, UTC 타임존으로 변경하면 0시를 확인할 수 있다.
OffsetDateTime
`OffsetDateTime` 은 `LocalDateTime` 에
UTC 오프셋 정보(UTC와 시간차이) `ZoneOffset` 이 합쳐진 것이다.
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
public class OffsetDateTimeMain {
public static void main(String[] args) {
OffsetDateTime nowOdt = OffsetDateTime.now();
System.out.println("nowOdt : "+nowOdt);
LocalDateTime ldt = LocalDateTime.of(2024, 6,12,12,8,20);
OffsetDateTime ofOdt = OffsetDateTime.of(ldt, ZoneOffset.of("+09:00"));
System.out.println("ofOdt : "+ofOdt);
}}
`ZoneOffset` 은 `+01:00` 처럼 UTC와의 시간 차이인 오프셋 정보만 보관한다.
**ZonedDateTime vs OffsetDateTime**
`ZonedDateTime` 은 구체적인 지역 시간대를 다룰 때 사용하며, 일광 절약 시간을 자동으로 처리할 수 있다. 사
용자 지정 시간대에 따른 시간 계산이 필요할 때 적합하다.
`OffsetDateTime` 은 UTC와의 시간 차이만을 나타낼 때 사용하며, 지역 시간대의 복잡성을 고려하지 않는다.
시간대 변환 없이 로그를 기록하고, 데이터를 저장하고 처리할 때 적합하다.
**참고**
`ZonedDateTime` 이나 `OffsetDateTime` 은 글로벌 서비스를 하지 않으면 잘 사용하지 않는다. 따라서 너무 깊이있
게 파기 보다는 대략 이런 것이 있다 정도로만 알아두면 된다. 실무에서 개발하면서 글로벌 서비스를 개발할 기회가 있
다면 그때 필요한 부분을 찾아서 깊이있게 학습하면 된다.
기간, 시간의 간격 - Duration, Period
Period**
두 날짜 사이의 간격을 년, 월, 일 단위로 나타낸다.
이 프로젝트는 3개월 정도 걸릴 것 같아기념일이 183일 남았어
프로젝트 시작일과 종료일 사이의 간격: 프로젝트 기간
**Duration**
두 시간 사이의 간격을 시, 분, 초(나노초) 단위로 나타낸다.
라면을 끓이는 시간은 3분이야
영화 상영 시간은 2시간 30분이야
서울에서 부산까지는 4시간이 걸려
Period
import java.time.LocalDate;
import java.time.Period;
public class PeriodMain {
public static void main(String[] args) {
Period period = Period.ofDays(10);
System.out.println("period "+period);
System.out.println("\n 계산");
LocalDate ldt = LocalDate.of(2024, 4, 5);
LocalDate plus = ldt.plus(period);
System.out.println("지정날짜 : "+ldt);
System.out.println("지정날짜 + period : "+plus);
System.out.println("/n 기간차이");
LocalDate now = LocalDate.now();
Period between = Period.between(plus, now);
System.out.println("지정날짜 : "+ldt);
System.out.println("현재날짜 : "+now);
System.out.println("기간 : "+between.getMonths()
+"개월 "+between.getDays()+"일");}}
출력
period : P10D
계산
지정날짜 : 2024-04-05
지정날짜 + period : 2024-04-15
기간차이
지정날짜 : 2024-04-05
현재날짜 : 2025-01-01
기간 : 8개월 17일
**생성**
`of()` : 특정 기간을 지정해서 `Period` 를 생성한다.
`of(년, 월, 일)`
`ofDays()`
`ofMonths()`
`ofYears()`
**계산에 사용**
2030년 1월 1일에 10일을 더하면 2030년 1월 11일이 된다.
라고 표현할 때 특정 날짜에 10일이라는 기간을 더함.
**기간 차이**
2023년 1월 1일과 2023년 4월 2일간의 차이는 3개월 1일이다. 라고 표현할 때 특정 날짜의 차이를 구하면 기간이 됨.
`Period.between(startDate, endDate) 와 같이 특정 날짜의 차이를 구하면 `Period` 가 반환/
Duration
import java.time.Duration;
import java.time.LocalTime;
public class DurationMain {
public static void main(String[] args) {
Duration duration = Duration.ofMinutes(40);
System.out.println("duration : "+duration);
LocalTime lt = LocalTime.of(4,0);
System.out.println("기준시간 : "+lt);
LocalTime plus = lt.plus(duration);
System.out.println("기준시간 + duration : "+plus);
LocalTime start = LocalTime.of(8, 0);
LocalTime end = LocalTime.of(15, 30);
Duration between = Duration.between(start, end);
System.out.println("시작 시간 : "+start);
System.out.println("종료 시간 : "+end);
System.out.println("차이(초) : "+between.getSeconds());
System.out.println("시간 차 : "+between.toHours()+"시간 "+
between.toMinutesPart()+"분 ");
}}
출력
duration : PT40M
기준시간 : 04:00
기준시간 + duration : 04:40
시작 시간 : 08:00
종료 시간 : 15:30
차이(초) : 27000
시간 차 : 7시간 30분
특정 시점의 시간: `Temporal` (`TemporalAccessor` 포함) 인터페이스를 구현한다.
구현으로 `LocalDateTime` , `LocalDate` , `LocalTime` , `ZonedDateTime` , `OffsetDateTime` ,
`Instant` 등이 있다.
시간의 간격(기간): `TemporalAmount` 인터페이스를 구현한다.
구현으로 `Period` , `Duration` 이 있다.
TemporalAccessor 인터페이스**
날짜와 시간을 읽기 위한 기본 인터페이스
이 인터페이스는 특정 시점의 날짜와 시간 정보를 읽을 수 있는 최소한의 기능을 제공한다.
**Temporal 인터페이스**
`TemporalAccessor` 의 하위 인터페이스로, 날짜와 시간을 조작(추가, 빼기 등)하기 위한 기능을 제공한다. 이
를 통해 날짜와 시간을 변경하거나 조정할 수 있다.
간단히 말하면, `TemporalAccessor` 는 읽기 전용 접근을, `Temporal` 은 읽기와 쓰기(조작) 모두를 지원한다.
**TemporalAmount 인터페이스**
시간의 간격(시간의 양, 기간)을 나타내며, 날짜와 시간 객체에 적용하여 그 객체를 조정할 수 있다. 예를 들어, 특정 날
짜에 일정 기간을 더하거나 빼는 데 사용된다.
시간의 단위와 시간 필드
다음으로 설명할 날짜와 시간의 핵심 인터페이스는
시간의 단위를 뜻하는`TemporalUnit` (`ChronoUnit` )과
시간의 각 필드를 뜻하는 `TemporalField` (`ChronoField` )이다.
시간의단위-TemporalUnit, ChronoUnit
TemporalUnit` 인터페이스는 날짜와 시간을 측정하는 단위를 나타내며, 주로 사용되는 구현체는
`java.time.temporal.ChronoUnit` 열거형으로 구현되어 있다.
`ChronoUnit` 은 다양한 시간 단위를 제공한다.
여기서 `Unit` 이라는 뜻을 번역하면 단위이다. 따라서 시간의 단위 하나하나를 나타냄
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
public class ChronoUnitMain {
public static void main(String[] args) {
int i = 0;
ChronoUnit[] values = ChronoUnit.values();
for (ChronoUnit chronoUnit : values) {
i++;
System.out.println(i+"."+chronoUnit);
}
System.out.println("\nHOURS : "+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());
System.out.println("\n 차이구하기");
LocalTime lt1 = LocalTime.of(15, 0);
LocalTime lt2 = LocalTime.of(22, 0);
long sBetween = ChronoUnit.SECONDS.between(lt1, lt2);
long MBetween = ChronoUnit.MINUTES.between(lt1, lt2);
System.out.println("1. "+lt1);
System.out.println("2. "+lt2);
System.out.println("몇초 차이인가 ? "+sBetween);
System.out.println("몇분 차이인가 ? "+MBetween);}}
출력
1.Nanos
2.Micros
3.Millis
4.Seconds
5.Minutes
6.Hours
7.HalfDays
8.Days
9.Weeks
10.Months
11.Years
12.Decades
13.Centuries
14.Millennia
15.Eras
16.Forever
HOURS : Hours
HOURS.Duration : 3600
DAYS : Days
DAYS.duration : 86400
차이구하기
1. 15:00
2. 22:00
몇초 차이인가 ? 25200
몇분 차이인가 ? 420
`ChronoUnit` 을 사용하면 두 날짜 또는 시간 사이의 차이를 해당 단위로 쉽게 계산할 수 있다.
예제 코드에서는 두 `LocalTime` 객체 사이의 차이를 초, 분 단위로 구한다
시간필드 -ChronoField
`ChronoField` 는 날짜 및 시간을 나타내는 데 사용되는 열거형이다. 이 열거형은 다양한 필드를 통해 **날짜와 시간의
특정 부분을 나타낸다.** 여기에는 연도, 월, 일, 시간, 분 등이 포함된다.
`TemporalField` 인터페이스는 날짜와 시간을 나타내는데 사용된다. 주로 사용되는 구현체는
`java.time.temporal.ChronoField` 열거형으로 구현되어 있다.
`ChronoField` 는 다양한 필드를 통해 날짜와 시간의 특정 부분을 나타낸다.
여기에는 연도, 월, 일, 시간, 분 등이 포함된다.
여기서 필드(Field)라는 뜻이 날짜와 시간 중에 있는 특정 필드들을 뜻한다. 각각의 필드 항목은 다음을 참고하자.
예를 들어 2024년 8월 16일이라고 하면 각각의 필드는 다음과 같다.
`YEAR` : 2024
`MONTH_OF_YEAR` : 8
`DAY_OF_MONTH` : 16
단순히 시간의 단위 하나하나를 뜻하는 `ChronoUnit` 과는 다른 것을 알 수 있다. `
ChronoField` 를 사용해야
날짜와 시간의 각 필드 중에 원하는 데이터를 조회할 수 있다
예제코드
import java.time.temporal.ChronoField;
public class ChronoFieldMain {
public static void main(String[] args) {
int i = 1;
ChronoField[] values = ChronoField.values();
for (ChronoField c : values) {
System.out.println(i+"."+c+" range : "+c.range());
i++;
}
System.out.println("\nMONTH_OF_YEAR.range() "
+ChronoField.MONTH_OF_YEAR.range());
System.out.println("\nDAY_OF_MONTH.range() "
+ChronoField.DAY_OF_MONTH.range());
}}
1.NanoOfSecond range : 0 - 999999999
2.NanoOfDay range : 0 - 86399999999999
3.MicroOfSecond range : 0 - 999999
4.MicroOfDay range : 0 - 86399999999
5.MilliOfSecond range : 0 - 999
6.MilliOfDay range : 0 - 86399999
7.SecondOfMinute range : 0 - 59
8.SecondOfDay range : 0 - 86399
9.MinuteOfHour range : 0 - 59
10.MinuteOfDay range : 0 - 1439
11.HourOfAmPm range : 0 - 11
12.ClockHourOfAmPm range : 1 - 12
13.HourOfDay range : 0 - 23
14.ClockHourOfDay range : 1 - 24
15.AmPmOfDay range : 0 - 1
16.DayOfWeek range : 1 - 7
17.AlignedDayOfWeekInMonth range : 1 - 7
18.AlignedDayOfWeekInYear range : 1 - 7
19.DayOfMonth range : 1 - 28/31
20.DayOfYear range : 1 - 365/366
21.EpochDay range : -365243219162 - 365241780471
22.AlignedWeekOfMonth range : 1 - 4/5
23.AlignedWeekOfYear range : 1 - 53
24.MonthOfYear range : 1 - 12
25.ProlepticMonth range : -11999999988 - 11999999999
26.YearOfEra range : 1 - 999999999/1000000000
27.Year range : -999999999 - 999999999
28.Era range : 0 - 1
29.InstantSeconds range : -9223372036854775808 - 9223372036854775807
30.OffsetSeconds range : -64800 - 64800
MONTH_OF_YEAR.range() 1 - 12
DAY_OF_MONTH.range() 1 - 28/31
날짜와 시간 조회
import java.time.LocalDateTime;
import java.time.temporal.ChronoField;
public class GetTimeMain {
public static void main(String[] args) {
LocalDateTime ldt = LocalDateTime.of(2024, 10,5,13,20,30);
System.out.println("ldt : "+ldt);
System.out.println("YEAR : "+ldt.get(ChronoField.YEAR));
System.out.println("MONTH_OF_YEAR : "+
ldt.get(ChronoField.MONTH_OF_YEAR));
System.out.println("DAY_OF_MONTH : "+
ldt.get(ChronoField.DAY_OF_MONTH));
System.out.println("HOUR_OF_DAY : "
+ldt.get(ChronoField.HOUR_OF_DAY));
System.out.println("MINUTE_OF_HOUR : "
+ldt.get(ChronoField.MINUTE_OF_HOUR));
System.out.println("SECOND_OF_MINUTE :"
+ldt.get(ChronoField.SECOND_OF_MINUTE));
System.out.println("\n @@편의메서드 사용@@");
System.out.println("YEAR : "+ldt.getYear());
System.out.println("MONTH_OF_YEAR : "+ldt.getMonthValue());
System.out.println("DAY_OF_MONTH : "+ldt.getDayOfMonth());
System.out.println("HOUR_OF_DAY : "+ldt.getHour());
System.out.println("MINUTE_OF_HOUR : "+ldt.getMinute());
System.out.println("SECOND_OF_MINUTE : "+ldt.getSecond());
System.out.println("\n 편의메서드에 없음");
System.out.println("MINUTE_OF_DAY "+ldt.get(ChronoField.MINUTE_OF_DAY));
System.out.println("SECOND_OF_DAY "+ldt.get(ChronoField.SECOND_OF_DAY));}}
**TemporalAccessor.get(TemporalField field)**
`LocalDateTime` 을 포함한 특정 시점의 시간을 제공하는 클래스는 모두 `TemporalAccessor` 인터페이스를
구현한다.
`TemporalAccessor` 는 특정 시점의 시간을 조회하는 기능을 제공한다.
`get(TemporalField field)` 을 호출할 때 어떤 날짜와 시간 필드를 조회할 지 `TemporalField` 의 구현
인 `ChronoField` 를 인수로 전달하면 된다.
**편의 메서드 사용**
`get(TemporalField field)` 을 사용하면 코드가 길어지고 번거롭기 때문에
자주 사용하는 조회 필드는 간단한 편의메서드제공
`dt.get(ChronoField.DAY_OF_MONTH)) -> dt.getDayOfMonth()`
날짜와 시간 조작
날짜와 시간을 조작하려면 어떤 시간 단위(Unit)를 변경할 지 선택해야 한다. 이때 날짜와 시간의 단위를 뜻하는
`ChronoUnit` 이 사용된다.
public class ChangeTimePlusMain {
public static void main(String[] args) {
LocalDateTime dt = LocalDateTime.of(2008, 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);
}
}
Temporal plus(long amountToAdd, TemporalUnit unit)**
`LocalDateTime` 을 포함한 특정 시점의 시간을 제공하는 클래스는 모두 `Temporal` 인터페이스를 구현한다.
`Temporal` 은 특정 시점의 시간을 조작하는 기능을 제공한다.
`plus(long amountToAdd, TemporalUnit unit)` 를 호출할 때 더하기 할 숫자와 시간의 단위(Unit)를
전달하면 된다. 이때 `TemporalUnit` 의 구현인 `ChronoUnit` 을 인수로 전달하면 된다.
불변이므로 반환 값을 받아야 한다.
참고로 `minus()`도 존재
**편의 메서드 사용**
자주 사용하는 메서드는 편의 메서드가 제공된다.
`dt.plus(10, ChronoUnit.YEARS) -> `dt.plusYears(10)`
**Period를 사용한 조작**
`Period` 나 `Duration` 은 기간(시간의 간격)을 뜻한다. 특정 시점의 시간에 기간을 더할 수 있다.
날짜와 시간 조작2
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 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);
}}
Temporal with(TemporalField field, long newValue)**
`Temporal.with()` 를 사용하면 날짜와 시간의 특정 필드의 값만 변경할 수 있다.
불변이므로 반환 값을 받아야 한다.
**편의 메서드**
자주 사용하는 메서드는 편의 메서드가 제공된다.
`dt.with(ChronoField.YEAR, 2020)-->` `dt.withYear(2020)`
**TemporalAdjuster 사용**
`with()` 는 아주 단순한 날짜만 변경할 수 있다. 다음 금요일, 이번 달의 마지막 일요일 같은 복잡한 날짜를 계산
하고 싶다면 `TemporalAdjuster` 를 사용하면 된다.
DayOfWeek**
월, 화, 수, 목, 금, 토, 일을 나타내는 열거형이다.
**TemporalAdjusters 클래스가 제공하는 주요 기능**
**메서드** **설명**
dayOfWeekInMonth 주어진 요일이 몇 번째인지에 따라 날짜를 조정한다.
firstDayOfMonth 해당 월의 첫째 날로 조정한다.
firstDayOfNextMonth 다음 달의 첫째 날로 조정한다.firstDayOfNextYear 다음 해의 첫째 날로 조정한다.
firstDayOfYear 해당 해의 첫째 날로 조정한다.
firstInMonth 주어진 요일 중 해당 월의 첫 번째 요일로 조정한다.
lastDayOfMonth 해당 월의 마지막 날로 조정한다.
lastDayOfNextMonth 다음 달의 마지막 날로 조정한다.
lastDayOfNextYear 다음 해의 마지막 날로 조정한다.
lastDayOfYear 해당 해의 마지막 날로 조정한다.
lastInMonth 주어진 요일 중 해당 월의 마지막 요일로 조정한다.
next 주어진 요일 이후의 가장 가까운 요일로 조정한다.
nextOrSame 주어진 요일 이후의 가장 가까운 요일로 조정하되, 현재 날짜가 주어진 요일인 경우 날짜를 반환한다.
previous 주어진 요일 이전의 가장 가까운 요일로 조정한다.
previousOrSame 주어진 요일 이전의 가장 가까운 요일로 조정하되, 현재 날짜가 주어진 요일인 경우 날짜를 반환한다.
날짜와시간 문자열파싱과 포맷팅
**포맷팅**: 날짜와 시간 데이터를 원하는 포맷의 문자열로 변경하는 것, `Date`->`String`
**파싱**: 문자열을 날짜와 시간 데이터로 변경하는 것, `String`-> Date`
public class FormattingMain1 {
public static void main(String[] args) {
LocalDate ld = LocalDate.now();
System.out.println("현재날짜 : "+ld);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일");
String format = ld.format(formatter);
System.out.println("format : "+format);
String input = "2023년 10월 04일";
LocalDate parse = LocalDate.parse(input,formatter);
System.out.println("parse : "+parse);
}}
현재날짜 : 2025-01-01
format : 2025년 01월 01일
parse : 2023-10-04
시간까지 더해서 포맷,파싱 가능!!!!
LocalDateTime ldt = LocalDateTime.of(2024, 10,20,13,30,00);
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일 HH시 mm분 ss초");
String format2 = ldt.format(formatter2);
System.out.println("ldt : "+ldt);
System.out.println("format2 :"+format2);
String input2 = "2000년 11월 20일 13시 20분 45초";
LocalDateTime parse2 = LocalDateTime.parse(input2,formatter2);
System.out.println("input : "+input2);
System.out.println("parse2 : "+parse2);
문제와풀이
문제1 - 날짜 더하기
**문제 설명**
2024년 1월 1일 0시 0분 0초에 1년 2개월 3일 4시간 후의 시각을 찾아라.
`TestPlus` 클래스에 문제를 풀어라.
public static void main(String[] args) {
LocalDateTime ldt = LocalDateTime.of(2024, 1,1,0,0,0);
LocalDateTime plus = ldt.plusYears(1).plusMonths(2).plusDays(3).plusHours(4);
System.out.println("변경 전 : "+ldt);
System.out.println("변경 후 : "+plus);
}
출력
변경 전 : 2024-01-01T00:00
변경 후 : 2025-03-04T04:00
문제2 - 날짜 간격 반복 출력하기
**문제 설명**
2024년 1월 1일 부터 2주 간격으로 5번 반복하여 날짜를 출력하는 코드를 작성하세요.
`TestLoopPlus` 클래스에 문제를 풀어라
LocalDate ld = LocalDate.of(2024,1 , 1);
System.out.println("변경 전 : "+ld);
for (int i = 1; i < 6; i++) {
LocalDate plusWeeks = ld.plusWeeks(2*i); //하지만 메서드를 사용하자!~~
//LocalDate plus = startDate.plus(2 * i, ChronoUnit.WEEKS); 이 방법도가능
System.out.println(i+"번쨰 변경 : "+plusWeeks);
}}
문제3 - 디데이 구하기
**문제 설명**
시작 날짜와 목표 날짜를 입력해서 남은 기간과 디데이를 구해라. 실행 결과를 참고하자.
남은 기간: x년 x개월 x일 형식으로 출력한다.
디데이: x일 남은 형식으로 출력한다.
public static void main(String[] args) {
LocalDate start = LocalDate.of(2025, 1, 2);
LocalDate end = LocalDate.of(2025, 1, 28);
System.out.println("시작 : "+start);
System.out.println("종료 : "+end);
long between = ChronoUnit.DAYS.between(start, end);
Period p = Period.between(start, end);
System.out.println(p.getYears()+"년 "+p.getMonths()+" 개월"
+p.getDays()+"일");
System.out.println("D-day : "+between+"일");
}
시작 : 2025-01-02
종료 : 2025-01-28
0년 0 개월26일
D-day : 26일
문제4 - 시작 요일, 마지막 요일 구하기
입력 받은 월의 첫날 요일과 마지막날 요일을 구해라.
public class TestAdjust {
public static void main(String[] args) {
int year = 2025;
int month = 1;
int day = 1;
LocalDate date = LocalDate.of(year, month, 1);
DayOfWeek first = date.getDayOfWeek();
DayOfWeek first2 = date.with(TemporalAdjusters.firstDayOfMonth()).getDayOfWeek();
DayOfWeek last = date.with(TemporalAdjusters.lastDayOfMonth()).getDayOfWeek();
System.out.println("첫날 요일 : "+first);
System.out.println("첫날 요일(다른방법) : "+first2);
System.out.println("마지막 요일 : "+last);
}}
'Java공부(코딩)' 카테고리의 다른 글
코딩초보의 자바(Java)공부 20일차 { 중첩클래스 , 내부클래스 2 } (0) | 2025.01.02 |
---|---|
코딩초보의 자바(Java)공부 20일차 { 중첩 클래스 , 내부클래스 1} (2) | 2025.01.02 |
코딩초보의 자바(Java)공부 18일차 { 열거형 -ENUM - } (0) | 2024.12.31 |
코딩초보의 자바(Java)공부 17일차 { 래퍼 , Class 클래스 } (5) | 2024.12.30 |
코딩초보의 자바(Java)공부 16일차 { String 클래스 } (4) | 2024.12.29 |