Date와 LocalDate차이점, 날짜 및 시간 처리하는 클래스의 변천사

시간순으로 클래스변천사를 나열해보았다.
바쁘니까 결론부터 보자

☝️결론

  • LocalDate와 LocalDateTime을 쓰자!

Java8부터는 LocalDate와 LocalDateTime이 등장했다.
그전에는 자바 기본 날짜타입인 Date클래스, Calenar클래스를 사용했는데 문제점이 꽤나 많아서 오픈소스인 JodaTime을 통해 문제점들을 피하곤했다.
하지만 Java8에서부터는 더이상 피할 필요가 없도록 LocalDate와 LocalDateTime이 추가되었다.

  • Date클래스, Calenar클래스 문제점
    1. 변하지 않는 객체가 아님
    2. Calenar.OCTOBER 숫자값이 9로 헷갈리게 설정되어있어 문제를 야기함




java.util.Date 클래스

  • deprecated처리되었지만 이미 작성된 많은 API가 파라미터나 리턴타입으로 Date를 여전히 사용.




java.util.Calendar 클래스

  • 정말 자주 사용하는 클래스.
  • switch문은 if조건문으로 변경해도 됨.

예시1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public static String getDateString(Calendar c){
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH)+1;
int date = c.get(Calendar.DATE);
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);

String day = null;
switch(dayOfWeek){
case Calendar.SUNDAY : day = "일";
break;
case Calendar.MONDAY : day = "월";
break;
case Calendar.TUESDAY : day = "화";
break;
case Calendar.WEDNESDAY : day = "수";
break;
case Calendar.THURSDAY : day = "목";
break;
case Calendar.FRIDAY : day = "금";
break;
case Calendar.SATURDAY: day = "토";
break;
default : System.out.println("다시입력해주세요");
}
return String.format("%d년 %d월 %d일(%s)", year, month, date, day);
}

public static String getTimeString(Calendar c){
int hour = c.get(Calendar.HOUR);
int minute = c.get(Calendar.MINUTE);
int second = c.get(Calendar.SECOND);
int amPm = c.get(Calendar.AM_PM);
String smPmString = (amPm == Calendar.AM ? "오전":"오후");
return String.format("%d시 %d분 %d초(%s)", hour, minute, second, smPmString);
}

public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
System.out.println("오늘은 : "+getDateString(cal));
System.out.println("지금 시각은 : "+getTimeString(cal));
int futureY = 2030;
cal.set(Calendar.YEAR, futureY);
System.out.println(futureY+"년 오늘은 : "+getDateString(cal));
}

//출력값
오늘은 : 202086일(목)
지금 시각은 : 94229초(오전)
2030년 오늘의 요일은 : 203086일(화)

예시2

  • Calendar.getInstance().set()을 통해서 연산의 첫 시작일을 셋팅할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public static String printSimpleCalendar(Calendar c){
int month = c.get(Calendar.MONDAY)+1;
int date = c.get(Calendar.DATE);
return String.format("%d월 %d일", month, date);
}

public static void main(String[] args){
Calendar cal = Calendar.getInstance();
//cal.set(Calendar.DATE, 23);
System.out.println("최초 : "+printSimpleCalendar(cal));
cal.add(Calendar.DATE, 20);
System.out.println("20일 add 후 : "+printSimpleCalendar(cal));
cal.roll(Calendar.DATE, -20);
System.out.println("-20일 roll 후 : "+printSimpleCalendar(cal));
}

//주석해제 전 출력값
최초 : 86
20일 add 후 : 826
-20일 roll 후 : 86

//주석해제 후 출력값
최초 : 823
20일 add 후 : 912
-20일 roll 후 : 922




java.time 패키지

  • java.util패키지 안에 date와 calendar 클래스만 있다가 여러 번거로움때문에 아예 패키지가 생겼다. 그것이 바로 time패키지이다.




날짜/시간 정보의 조회와 변경

  • LocalDate, LocalTime, LocalDateTime : 현재 소속된 로컬의 시간과 날짜정보를 다루는 클래스.

  • ZoneDateTime : 특정 타임존의 날짜와 시간을 다루는 클래스.(LocalDate, LocalTime, TimeZone이 합쳐진 형태이다)

  • 위 클래스들의 공통 정적 메서드 2가지:

    • now() : 현재 시각을 기준으로 날짜 또는 시간 정보를 갖는 객체를 리턴.
    • of() : 각 객체가 가지는 요소들(LocalDate는 년/월/일정보, LocalTime은 시/분/초)을 파라미터로 받아서 객체를 생성.
  • 참고링크 : java.time패키지 모든 클래스 및 메서드

https://palpit.tistory.com/909

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) {
LocalDateTime datetime = LocalDateTime.of(1991, 12,25,12,30,1);
LocalDateTime curdatetime = LocalDateTime.now();
System.out.println("기준일 : " + datetime + "-" + datetime.getDayOfWeek());
LocalDateTime lastday = datetime.with(TemporalAdjusters.lastDayOfYear());
LocalDateTime curdatetimelast = curdatetime.with(TemporalAdjusters.lastDayOfMonth());
System.out.println("지정한 한 해의 마지막일 : " + lastday + "-" + lastday.getDayOfWeek());
System.out.println("올해 이번달 마지막일 : " + curdatetimelast + "-" + curdatetimelast.getDayOfWeek());

}
//출력값
기준일 : 1991-12-25T12:30:01-WEDNESDAY
지정한 한 해의 마지막일 : 1991-12-31T12:30:01-TUESDAY
올해 이번달 마지막일 : 2020-08-31T11:34:23.765-MONDAY




날짜와 시간 비교

  • Period.between() : 년/월/일 차이 계산(각 단위별로 연산)
  • Duration.between() : 초/나노 초 계산(총 시간을 기준으로 연산)
  • ChronoUnit.XXX.between() : 모든 단위 계산(총 시간을 기준으로 연산)

참고링크 : 날짜와 시간 비교하기 표

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public static void main(String[] args) {
LocalDate date1 = LocalDate.of(1953, 8, 15);
LocalDate date2 = LocalDate.now();
Period p = Period.between(date1, date2);
System.out.println(p);
System.out.println("몇 년 차이 ? "+ p.getYears());
System.out.println("몇 월 차이 ? "+ p.getMonths());
System.out.println("몇 일 차이 ? "+ p.getDays());

long monDiff = ChronoUnit.MONTHS.between(date1, date2);
System.out.println("총 몇 개월 차이 ? "+monDiff);

LocalDateTime dt1 = LocalDateTime.of(2011, 3, 01, 1,1,1);
LocalDateTime dt2 = LocalDateTime.of(2020, 3, 01, 1,1,1);
Duration d = Duration.between(dt1, dt2);
System.out.println(d);
System.out.println("getSeconds사용한 몇 초 차이? "+d.getSeconds());
long secDiff = ChronoUnit.SECONDS.between(dt1, dt2);
System.out.println("chronounit사용한 몇 초 차이? "+ secDiff);
}
//출력값
P66Y11M22D
몇 년 차이 ? 66
몇 월 차이 ? 11
몇 일 차이 ? 22
총 몇 개월 차이 ? 803
PT78912H
getSeconds사용한 몇 초 차이? 284083200
chronounit사용한 몇 초 차이? 284083200




날짜와 시간 표현

  • 포맷팅 : 객체를 원하는 형태의 문자열로 변환하는 과정. 파싱의 반대.
  • 파싱 : 문자열을 객체로 변경하는 과정. 포맷팅의 반대.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void main(String[] args) {
LocalDateTime date = LocalDateTime.of(2011, 2,5,1,11,0);
System.out.printf("기본 날짜 출력 : %s%n", date);
System.out.println(date.format(DateTimeFormatter.BASIC_ISO_DATE));
System.out.println(date.format(DateTimeFormatter.ISO_LOCAL_DATE)); //추천
System.out.println(date.format(DateTimeFormatter.ISO_LOCAL_TIME));
System.out.println(date.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
System.out.println(date.format(DateTimeFormatter.ISO_ORDINAL_DATE));
System.out.println(date.format(DateTimeFormatter.ISO_WEEK_DATE));
}
//출력값
기본 날짜 출력 : 2011-02-05T01:11
20110205
2011-02-05
01:11:00
2011-02-05T01:11:00
2011-036
2011-W05-6