JDK 1.0 부터 생긴 - java.util.[Date 클래스] 는 deprecated 메소드(사라질 예정인 것)
1) 객체 생성 방법
//디폴트 생성자는 현재 시스템의 날짜, 시간 정보를 얻어온다.
//=> 생성할 때 현재 날짜, 시간을 가진 객체가 만들어진다는 것
Date d = new Date();
//원하는 날짜의 객체 생성도 가능
Date d = new Date(year-1900, month-1, date);
2) 출력
//아래 둘은 같은 시간정보 값을 갖는다.
//Thu Feb 23 14:32:02 KST 2023 (KST: 한국표준시)
System.out.println(d.toString()); //위에서 만들어진 객체정보를 출력하는게 toString()
System.out.println(d);
3) 날짜를 보기 쉽게 표시해주는 toGMTString(), toLocaleString()
System.out.println(d.toGMTString()); //23 Feb 2023 05:38:12 GMT (GMT: 그리니치 평균시간 = 세계표준시간)
System.out.println(d.toLocaleString()); //2023. 2. 23. 오후 2:38:12 (로컬, 해당지역에서 쓰는대로)
4) 메소드
//년
System.out.println(d.getYear() + 1900); //1900 뺀 값으로 나오므로 더해줘야 제대로 나옴
//월
System.out.println(d.getMonth()+1); //1~12월이 0~11까지 나옴
//일
System.out.println(d.getDate()); //날짜 중 일 정보를 얻어옴
//요일
System.out.println(d.getDay()); //0은 일요일, 1은 월요일, ~ 6은 토요일 // 목(4)
System.out.println("일월화수목금토".charAt(d.getDay()) + "요일"); //문자열에서 원하는 위치의 한 문자를 얻어옴
//시간
System.out.println(d.getHours());
//분
System.out.println(d.getMinutes());
//초
System.out.println(d.getSeconds());
Date d2 = new Date();
d2.setYear(2010-1900);
d2.setMonth(5-1);
d2.setDate(1);
d2.setHours(0);
d2.setMinutes(0);
d2.setSeconds(0);
5) 예제
System.out.println("일월화수목금토".charAt(d.getDay())); //토요일
String rrn = "890223-1";
Date today = new Date();
//시간, 분, 초를 맞춰주지 않으면 시간에 따라서도 지났다, 안 지났다 결과가 바뀌어서 set으로 맞춰줘야 한다.
today.setHours(0);
today.setMinutes(0);
today.setSeconds(0);
//생일이 동일한지 알기 위해서는 밀리세컨드값까지 동일하게 맞춰야 한다.
//getTime() 을 이용하면 1970 1월 1일부터 지금까지의 밀리세컨드값을 long 형으로 반환해준다.
today.setTime(today.getTime() - today.getTime() % 1000);
Date b_day = new Date(2023-1900, 2-1, 23, 0, 0, 0); //생일 날짜 객체
b_day.setTime(b_day.getTime() - b_day.getTime() % 1000);
System.out.println(b_day); //Sat Feb 23 00:00:00 KST 2023 여기는 시간, 분, 초가 0!!
System.out.println(today.after(b_day)); //날짜가 지났는지 안 지났는지에 따라 boolean 값을 돌려준다. true: 생일 지남, false: 안 지남
System.out.println(today.before(b_day)); //오늘 날짜가 생일 이전인지에 따라 boolean 값을 돌려준다. true: 생일 안 지남, false: 지남
System.out.println(today.equals(b_day)); //오늘이 생일인지
JDK 1.1 부터 생긴 - java.util.Calendar, 추상 클래스 (자식클래스로 GregorianCalendar가 있다.)
1) 객체 생성 방법
1. getInstance() 이용
Calendar c = Calendar.getInstance();
2. 자식 클래스 이용
Calendar c1 = new GregorianCalendar();
3. 원하는 날짜의 객체 생성도 가능
Calendar c = new GregorianCalendar(2010, 5-1, 1);
2) 출력
//아래 둘은 같은 시간정보 값을 갖는다.
System.out.println(c);
System.out.println(c.toString);
3) 메소드
//여기서는 사용불가(컴파일 오류)
Calendar c1 = new GregorianCalendar(); //Calendar 클래스를 상속받은 GregorianCalendar 클래스의 객체를 생성
//이렇게 생성한 객체는 참조 변수 c1이 Calendar 타입으로 선언되어 있기 때문에, Calendar 클래스에서 정의된 메소드만 사용가능하다.
c1.isLeapYear(2010);
//자식 -> 부모 로 참조시키는 건 가능하지만, 부모 -> 자식으로의 참조는 불가능
//여기서는 사용가능
GregorianCalendar c2 = new GregorianCalendar(); //구체적인 자식클래스로 생성한 객체를 참조 변수 c2로 선언
//c2는 GregorianCalendar 타입의 객체이므로, GregorianCalendar 클래스에서 정의된 isLeapYear() 메소드 사용가능
c2.isLeapYear(2010);
//빼기 메소드는 없고, 더하기 메소드만 있다.
//하루 빼서 마지막 날짜를 구하기
Calendar c2 = new GregorianCalendar(2010, 6-1, 1); //2010-06-01
c2.add(Calendar.DATE, -1); //add 밖에 없어서 -1 더해줘서 5월의 마지막날 만듬
System.out.println(c.get(Calendar.DATE)); //31
roll() ??
비교하는 메소드 after(), before(), equals(), compareTo()
String rrn = "980226";
int month = Integer.parseInt(rrn.substring(2, 4));
int day = Integer.parseInt(rrn.substring(4));
Calendar t = Calendar.getInstance();
//이거 다 초기화 해줘야 제대로 결과 나옴
t.set(Calendar.HOUR_OF_DAY, 0);
t.set(Calendar.MINUTE, 0);
t.set(Calendar.SECOND, 0);
t.set(Calendar.MILLISECOND, 0);
//t.clear(Calendar.MILLISECOND); 밀리세컨드 초기화는 이거랑도 같음
Calendar b = new GregorianCalendar(t.get(Calendar.YEAR), month-1, day); //연도만 맞추고 월은 1 뺌
System.out.println(t.getTimeInMillis()); //밀리세컨드 초기화 확인, long형 1677164400000
System.out.println(b.getTimeInMillis()); //밀리세컨드 초기화 확인
System.out.println(t.after(b)); //true
System.out.println(t.before(b)); //false
System.out.println(t.equals(b)); //false
System.out.println(t.compareTo(b)); //동일하면 0, 지났으면 1, 지나지 않았으면 -1 을 반환한다.
//Calender 클래스는 매개변수로 주어진 필드값이 존재한다.
//local fields (YEAR(1), MONTH(2), DATE(3), HOUR(4), MINUTE(5), etc.)
//년
System.out.println(c.get(1)); //public static final int YEAR= 1; 상수이자 static으로 클래스명으로도 접근가능. 상수화 되어있는 것.
System.out.println(c.get(Calendar.YEAR));
//월
System.out.println(c.get(Calendar.MONTH) + 1); //2
//주
System.out.println(c.get(Calendar.WEEK_OF_MONTH)); //4, 해당 월의 몇번째 주인지
System.out.println(c.get(Calendar.WEEK_OF_YEAR)); //8, 해당 년도의 몇번째 주인지
//일 , 밑에 둘은 동일한 값을 갖는다.
System.out.println(c.get(Calendar.DATE)); //23
System.out.println(c.get(Calendar.DAY_OF_MONTH)); //23, 해당 월의 며칠째인지
//365일 중 며칠째?
System.out.println(c.get(Calendar.DAY_OF_YEAR)); //54, 해당 년도의 며칠째인지
//요일
System.out.println(c.get(Calendar.DAY_OF_WEEK)); //5(목요일), 일:1, 월:2, 화:3, 수:4, 목:5, 금:6, 토:7
//Date 클래스는 0(일)~6(토)임
//시간
System.out.println(c.get(Calendar.HOUR_OF_DAY)); //16, 24시간 기준(0~23)
System.out.println(c.get(Calendar.HOUR)); //4, 12시간 기준(0~11)
System.out.println(c.get(Calendar.AM_PM)); //1, 오전/오후 (AM:0, PM:1)
//분
System.out.println(c.get(Calendar.MINUTE)); //36
//초
System.out.println(c.get(Calendar.SECOND)); //5
//밀리세컨드
System.out.println(c.get(Calendar.MILLISECOND)); //535
t.set(Calendar.HOUR, 0);
t.set(Calendar.MINUTE, 0);
t.set(Calendar.SECOND, 0);
t.set(Calendar.MILLISECOND, 0);
//t.clear(Calendar.MILLISECOND); 밀리세컨드 초기화는 이거랑도 같음
4) 예제
System.out.println("일월화수목금토".charAt(c.get(Calendar.DAY_OF_WEEK) -1 )); //토요일
int lastDay = c.getActualMaximum(Calendar.DAY_OF_MONTH);
System.out.println(lastDay);
int year;
try (Scanner sc = new Scanner(System.in)){
System.out.println("년도를 입력하세요. ");
year = sc.nextInt();
System.out.printf("%d년\n", year);
Calendar c = new GregorianCalendar(year, 1-1, 1); //200n년 1월 1일 객체
for (int i = 1; i <= 12; i++) {
//캘린더의 월을 i 값으로 수정해야 한다.
c.set(Calendar.MONTH, i-1);
int lastDay = c.getActualMaximum(Calendar.DATE);
System.out.printf("%d월 : %d일\n", 1, lastDay);
}
} catch (Exception e) {
e.printStackTrace();
}//try - catch
Calendar s = new GregorianCalendar(2023, 1-1, 26, 9, 0, 0);
Calendar t = Calendar.getInstance(); //시간, 분, 초, 밀리세컨드
long sTime = s.getTimeInMillis();
long tTime = t.getTimeInMillis();
long gab = tTime - sTime;//개강일~오늘(현재)까지 흐른 ms
System.out.println(gab); //2512782133 ms
System.out.println(gab/1000 + "초");
System.out.println(gab/(60*1000) + "분");
System.out.println(gab/(60*60*1000) + "시간");
System.out.println(gab/(24*60*60*1000) + "일");
int[] time = {
24*60*60*1000,
60*60*1000,
60*1000,
1000,
1
};
for (int i = 0; i < time.length; i++) {
System.out.print(gab/time[i]+"_");
gab %=time[i];
}
Calendar today = Calendar.getInstance();
Calendar start = new GregorianCalendar();
start.set(2023, 2-1, 17, 0, 0, 0);
Calendar end = new GregorianCalendar();
end.set(2023, 2-1, 26, 18, 0, 0); //끝나는 날짜도 포함됨!!
long startTime = start.getTimeInMillis();
long endTime = end.getTimeInMillis();
long todayTime = today.getTimeInMillis();
if (startTime <= todayTime && todayTime <= endTime) {
System.out.println("설문이 가능합니다.");
} else {
System.out.println("설문조사 기간이 종료되었습니다.");
}
Date d2 = new Date();
Calendar c2 = Calendar.getInstance();
c2.setTime(d2);
Calendar c1 = Calendar.getInstance();
Date d1 = new Date(c1.getTimeInMillis());
int year = 2023;
int month = 2;
Calendar c = new GregorianCalendar(year, month-1, 1); //23년도 2월 1일
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);//1(일) ~ 7 (토)
c.add(Calendar.DATE, -(dayOfWeek)); //23년도 2월 1일에 dayOfWeek 만큼 빼자는거
System.out.println("-".repeat(55));
System.out.println("-".repeat(55));
for (int i = 1; i <= 42; i++) {
c.add(Calendar.DATE, 1);
int outMonth = c.get(Calendar.MONTH) + 1;
/*
if(outMonth == month) System.out.printf("%d\t", c.get(Calendar.DATE));
else System.out.printf("(%d)\t", c.get(Calendar.DATE)); */
System.out.printf(outMonth == month? "[%d]\t" : "(%d)\t", c.get(Calendar.DATE) );
if(i % 7 == 0) System.out.println();
}//for
System.out.println("-".repeat(55));
// Calendar 객체를 Date 타입으로 형변환 하면 toLocaleString 쓸 수 있으니 형변환 해보자.
//Date d = new Date(c.getTimeInMillis()); //매개변수로 long형 입력가능하므로 입력
//System.out.println(d.toLocaleString());
JDK 1.8 부터 생긴 - java.time 패키지 안에 있는 여러 하위패키지 + 다양한 클래스 추가
① 구조에 대한 이해
하위 패키지명
모두 immutable!
1. j.t.chrono : 표준(ISO)가 아닌 달력 시스템을 위한 클래스들을 제공하는 패키지
2. j.t.format : 날짜와 시간의 형식화, 파싱 클래스 제공
3. j.t.temporal : 날짜와 시간의 필드(field)와 단위(unit) 클래스 제공
4. j.t.zone : 시간대(time-zone) 클래스 제공
② j.t 패키지의 핵심클래스(주로 사용되는 클래스)
j.t 패키지의 핵심클래스
1. 날짜를 다루는 LocalDate 클래스
2. 시간을 다루는 LocalTime 클래스
3. 날짜 + 시간을 다루는 LocalDateTime 클래스
4. 날짜 + 시간 + 시간대를 다루는 ZonedDateTime 클래스
//객체 생성
LocalDate d = LocalDate.now();
System.out.println(d); //2023-02-27
//년
int year = d.get(ChronoField.YEAR); //2023
//Temporal field를 달라고 하는데 이게 Chrono를 구현한거니까
d.getYear(); //2023
//월
int month = d.get(ChronoField.MONTH_OF_YEAR); //1~12 반환
System.out.println(month); //2
Month month2 = d.getMonth(); //열거형 enum
System.out.println(month2); //FEBRUARY
int month3 = d.getMonthValue(); //1~12 반환
System.out.println(month3); //2
//일
int day = d.getDayOfMonth();
System.out.println(day); //27
day = d.get(ChronoField.DAY_OF_MONTH);
System.out.println(day); //27
//요일
DayOfWeek dof = d.getDayOfWeek(); //enum
System.out.println(dof); //MONDAY
System.out.println(dof.getValue()); //1, 월(1) 화(2) ~ (6)토, (7)일
Ex) 생일이 오늘 기준으로 지났는지 여부를 체크한다면?
//시간: LocalTime은 안됨
LocalDate t = LocalDate.now(); //2023-02-27
int tyear = t.getYear();
LocalDate d = LocalDate.of(tyear, 2, 26);
//1998.02.26
System.out.println(t.isAfter(d)); //true
System.out.println(t.isBefore(d)); //false
System.out.println(t.isEqual(d)); //false
//객체 생성
LocalTime t = LocalTime.now();
System.out.println(t);
//시간
System.out.println(t.getHour());
//분
System.out.println(t.getMinute());
//초
System.out.println(t.getSecond());
//밀리초
System.out.println(t.get(ChronoField.MILLI_OF_SECOND));
//나노초
System.out.println(t.getNano());
System.out.println(t.get(ChronoField.NANO_OF_SECOND)); //위에랑 같은거
Ex) 1시간 10분 후?
t = t.plusHours(1);
t = t.plusMinutes(10);
System.out.println(t);
LocalDate & LocalTime 의 특징 정리
1. 특정 필드값을 변경하려면 with()으로 시작하는 메소드를 사용(항상 새로운 객체 반환)
2. 날짜와 시간의 비교 - isAfter(), isBefore(), isEqual(), compareTo()
3. 월의 범위는 1 ~ 12, 요일은 월요일(1) ~ 일요일(7)
- Date 클래스에서는 1(일) ~ 7(토)
- Calender 1(일) ~ 7(토)
- LocalDate & LocalTime 1(월) ~ 7(일) : ISO 표준은 월요일이 1
//객체 생성
LocalDateTime dt = LocalDateTime.now();
System.out.println(dt); //2023-02-27T10:40:03.704389300 날짜, 시간 정보가 모두 들어감
LocalDate d = LocalDate.now(); //날짜만
LocalTime t = LocalTime.now(); //시간만
방법1) 메소드 of()에 인자값으로 of(date, time) 주기
LocalDateTime dt = LocalDateTime.of(d, t);
방법2) 메소드 atTime(t)
LocalDateTime dt2 = d.atTime(t);
방법3) 메소드 atDate(d)
LocalDateTime dt3 = t.atDate(d);
방법4) 메소드 atStartOfDay()
LocalDateTime dt4 = d.atStartOfDay(); //00:00:00.000으로 셋팅
//시간 밑으로 모두 절삭(분, 초, 나노초)
dt = dt.truncatedTo(ChronoUnit.HOURS);
System.out.println(dt); //2023-02-27T10:00
//날짜 밑으로 모두 절삭
dt = dt.truncatedTo(ChronoUnit.DAYS);
System.out.println(dt); //2023-02-27T00:00
③ j.t 패키지의 메소드
1) 객체를 생성하는 now(), of()
→ 핵심클래스(LocalDate, LocalTime, LocalDateTime, ZonedDateTime)는 모두 new 연산자로 객체를 생성하지 않는다.
→ 객체를 생성하기 위해서는 now()를 이용한다.(현재 시스템 날짜, 시간 기준으로 된 객체 생성)
→ 그럼 내가 원하는 날짜나 시간대의 객체를 생성하려면? of() 사용.
→ 이렇게 객체를 생성하는 메소드에는 now(), of() 두가지 방법 밖에 없다.
2) 특정 필드값(년, 월, 일, 시, 분, 초, 밀리세컨드, 요일 등)을 가져오는 두가지 메소드 get(), getXXX()
두가지 메소드를 쓸 수 있다. => 필드 설정 시 필드에 해당되는 값을 가져옴
LocalDateTime now = LocalDateTime.now();
int year = now.get(ChronoField.YEAR);
LocalDate now = LocalDate.now();
Month month = now.getMonth(); //getMonth() 메소드를 호출하여 Month 열거형 객체를 반환
int monthValue = now.getMonthValue(); //getMonthValue() 메소드를 호출하여 해당 월의 값을 정수로 반환
④ 인터페이스 TemporalField
⑤ 인터페이스 TemporalUnit
LocalDate start = LocalDate.of(2022, Month.JANUARY, 1);
LocalDate end = LocalDate.of(2022, Month.JANUARY, 10);
long daysBetween = ChronoUnit.DAYS.between(start, end);
Ex) ChronoUnit.SECONDS, ChronoUnit.MINUTES, ChronoUnit.HOURS, ChronoUnit.DAYS 등
TemporalField와 TemporalUnit
- java.time 패키지에서 날짜와 시간을 다루기 위한 인터페이스
- TemporalField는 년, 월, 일 등 날짜와 시간의 특정 필드를 정의하는 인터페이스로 시간 값에서 필드 값을 가져오거나 필드 값을 설정하는 데 사용
- TemporalUnit은 날짜와 시간의 단위를 정의하는 인터페이스로 시간 차이를 계산하거나 특정 시간 단위로 시간 값을 조정하는 데 사용
ChronoField와 ChronoUnit
- ChronoField와 ChronoUnit은 각각 TemporalField와 TemporalUnit을 구현한 열거형 상수
- ChronoField: 시간의 특정 필드를 정의,
- ChronoUnit: java.time.temporal 패키지 소속, 시간의 기본 단위를 정의, 경우에 따라 총 며칠의 차이가 있는지 계산하고 싶을 때 사용(특정 날짜와 시간에서 지정된 단위의 값을 더하거나 뺄 때는 plus() 또는 minus()의 값과 함께 열거형 ChronoUnit 사용)
⑥ 간격을 다루는 클래스 Period & Duration
Period & Duration의 차이점
- Duration 클래스는 특정 시간 간격을 나타내는 클래스로, 초와 나노초 단위의 값을 갖는다. 따라서 Duration 객체는 초와 나노초를 기준으로만 시간 간격을 표현할 수 있으며, 일, 시간, 분 단위의 값을 직접 가져올 수 없다.
- 이와 달리 Period 클래스는 날짜를 기준으로 한 시간 간격을 나타내는 클래스로, 년, 월, 일 단위의 값을 직접 가져올 수 있다.
- Period 클래스는 범용메소드 get()을 갖지만, Duration 클래스는 get()을 사용할 수 없다.
Duration 클래스에 get() 메소드가 없는 이유?
- Period 클래스는 날짜를 기준으로한 시간 간격을 나타내는 클래스로, 년, 월, 일 단위의 값을 직접 가져올 수 있으므로 get 메소드를 사용하여 년, 월, 일 등의 값을 가져올 수 있다.
- Duration 클래스는 초와 나노초 단위의 값을 기준으로 시간 간격을 표현하기 때문에 분, 시간 등의 단위를 직접 가져올 수 없다.
- 따라서 Duration 객체를 사용하여 시간 간격을 구할 때는 toXXX 메소드를 통해 초와 나노초 값을 다른 단위로 변환하여 사용해야 한다.
- 이 때문에 LocalTime 객체를 활용하여 Duration 객체의 값을 LocalTime 객체로 변환한 다음, LocalTime 객체에서 단일 메소드인 getXXX 메소드를 이용해 각 단위 값을 가져와 사용하는 것이다.
▶ Duration 클래스에서 toXXX 메소드를 이용해 초와 나노초 값을 다른 단위로 변환하는 예시
Duration duration = Duration.ofHours(3).plusMinutes(30); //3시간 30분
long minutes = duration.toMinutes(); // 시간을 분으로 변환
System.out.println(minutes); // 210
long seconds = duration.getSeconds(); // 초를 가져옴
System.out.println(seconds); // 12600
long millis = duration.toMillis(); // 밀리초로 변환
System.out.println(millis); // 12600000
long days = duration.toDays(); // 일 단위로 변환
System.out.println(days); // 3시간 30분은 하루 이상이므로 0
long hours = duration.toHours(); // 시간 단위로 변환
System.out.println(hours); // 3
1) 날짜와 날짜 사이의 간격을 다루는 Period 클래스
Ex1)
// 개강일
LocalDate o = LocalDate.of(2023, 1, 26);
// 오늘일
LocalDate t = LocalDate.now();
//날짜 - 날짜 간격(차)
Period p = Period.between(o, t); //앞의 날짜는 포함이 되고, 마지막 날짜는 포함이 안 됨, 포함하려면 +1 해준다.
// 개강일(2023-01-26) - 오늘일(2023-02-28) 간격
long year = p.get(ChronoUnit.YEARS);
System.out.println(year); //0
long month = p.get(ChronoUnit.MONTHS);
System.out.println(month); //1
long day = p.get(ChronoUnit.DAYS);
System.out.println(day); //2
Ex2)
LocalDate d1 = LocalDate.of(2014, 1, 1);
LocalDate d2 = LocalDate.of(2015, 12, 31);
//두 날짜 사이의 간격 체크: Period
Period p = Period.between(d1, d2); //d1은 포함 O, d2는 포함 x
System.out.println(d1); //2014-01-01
System.out.println(d2); //2015-12-31
System.out.println(p); //P1Y11M30D 1년, 11월, 30일의 간격이 있다는 것
//toTotalMonths()는 일은 무시하고 년과 월을 월 단위로 변환해 반환하는 메소드
System.out.println(p.toTotalMonths()); //총 23개월
LocalDate t = LocalDate.now();
LocalDate b = LocalDate.of(2023, 5, 26);
Period p = t.until(b);
2) 시간과 시간 사이의 간격을 다루는 Duration 클래스
Ex1) 9:00:00 ~ 현재시간?
LocalTime oTime = LocalTime.of(9, 0, 0);
LocalTime tTime = LocalTime.now();
Duration d = Duration.between(oTime, tTime);
/*그런데 여기서 long hour = d.get(ChronoUnit.HOURS); 는 오류가 발생해 사용할 수 없다. 왜?
Duration 클래스에는 get 메소드가 없고, Duration의 객체 d 는 초와 나노초만 가져올 수 있기 때문!
Duration 클래스는 특정 시간 간격을 나타내는 클래스로,
이 클래스는 특정 단위 (예: 시간, 분, 초)의 값을 직접 가져올 수 있는 get 메서드를 제공하지 않는다.
long min = d.get(ChronoUnit.MINUTES); X
long sec = d.get(ChronoUnit.SECONDS); X
*/
//따라서 이렇게 만들어야 한다.
LocalTime diff = LocalTime.of(0, 0).plusSeconds(d.getSeconds());
int hour = diff.getHour();
int min = diff.getMinute();
int second = diff.getSecond();
int nano = d.getNano();
Ex2) 수업 시작한지 몇 초 지났는지?
LocalTime s = LocalTime.of(9, 0);
LocalTime t = LocalTime.now();
Duration d = Duration.between(s, t);
System.out.println(d); //PT3H7M4.3628194S
System.out.println(d.toHours()); //3hr
System.out.println(d.toMinutes()); //187m = 3*60 +5
System.out.println(d.toSeconds()); //11277
⑦ 메소드 정리
⑧ Instant 클래스(java.time.Instant)
Instant now = Instant.now();
System.out.println(now); //2023-02-27T01:28:50.211084100Z
System.out.println(now.getNano()); //211084100 이게 에포크 타임
Date d = new Date();
Instant n = d.toInstant();
Instant instant = Instant.now(); // 현재 시각을 Instant 객체로 생성
Date date = Date.from(instant); // Instant 객체를 Date 객체로 변환
//Java 8 이후 Date 클래스 대신 LocalDateTime, ZonedDateTime 등을 사용하는 경우 Instant 객체를 변환하면?
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
⑨ TemporalAdjusters 클래스(java.time.temporal)
//객체선언
LocalDate d = LocalDate.now();
System.out.println(d); //2023-02-27
System.out.println(d.with(TemporalAdjusters.firstDayOfNextMonth())); //2023-03-01
System.out.println(d.with(TemporalAdjusters.firstDayOfMonth())); //2023-02-01
System.out.println(d.with(TemporalAdjusters.firstDayOfYear())); //2023-01-01
System.out.println(d.with(TemporalAdjusters.firstDayOfNextYear())); //2024-01-01
System.out.println(d.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY))); //2023-02-06
System.out.println(d.with(TemporalAdjusters.lastInMonth(DayOfWeek.SATURDAY))); //2023-02-25
System.out.println(d.with(TemporalAdjusters.next(DayOfWeek.FRIDAY))); //2023-03-03
System.out.println(d.with(TemporalAdjusters.dayOfWeekInMonth(3, DayOfWeek.SATURDAY))); //2023-02-18
System.out.println(d.with(TemporalAdjusters.previous(DayOfWeek.SATURDAY))); //당일 미포함 2023-02-25
System.out.println(d.with(TemporalAdjusters.previousOrSame(DayOfWeek.SATURDAY))); //당일 포함 2023-02-25
참고
TemporalAdjuster 인터페이스를 구현하려면 adjustInto() 메소드를 오버라이드하여 날짜와 시간을 수정하는 로직을 구현해야 한다. 즉, adjustInto() 메소드는 주어진 Temporal 객체를 수정하고, 수정된 Temporal 객체를 반환해야 한다.
따라서, DayAfter3일 클래스에서 adjustInto() 메소드를 오버라이드하여 날짜를 수정하는 로직을 통해 TemporalAdjuster 인터페이스를 구현한 것. DayAfter3일 클래스의 adjustInto() 메소드에서는 입력으로 받은 Temporal 객체를 3일 뒤로 이동시킨 후, 수정된 Temporal 객체를 반환한다.
이와 같이 TemporalAdjuster 인터페이스를 구현하여 날짜를 수정할 수 있다. 이 방법을 사용하면 일정한 패턴에 따라 날짜를 자동으로 수정할 수 있으며, 코드의 가독성을 높이고 유지보수를 쉽게 할 수 있다.
//d = d.plusDays(3); 해도 되지만, 클래스를 만들어보자
d = d.with(new DayAfter3일());
System.out.println(d);
class DayAfter3일 implements TemporalAdjuster{
@Override
public Temporal adjustInto(Temporal temporal) {
return temporal.plus(3, ChronoUnit.DAYS);
}
}