본문 바로가기
Work/Java

[Java] 시간과 날짜 Class - 정리

자바에서 시간과 날짜를 제공하는 Class는 크게 Date, Calendar, Time 총 3가지로 볼 수 있다.

Date, Calendar java.util 패키지에 포함되어있던 아이들이고

LocalTime ,LocalDate, LocalDateTime 은  java.time 패키지 안에 각각 존재한다

 

 

과거에 사용하던 Date, Calendar 클래스에 문제가 너무 많아서 사용이 지양되고 있고,

새롭게 만들어진   java.time 패키지에 LocalTime ,LocalDate, LocalDateTime 를 사용하는 추세이다.

 

1. Date

https://docs.oracle.com/javase/8/docs/api/

API문서를 통해 보면, 

 

 

대부분이 Deprecated 되어있다. 더이상 사용하지 않으며,

언제 사라질지 모르는 메소드이므로 사용을 지양하라는 의미이다.

 

Date 클래스가 가지는 특징

  • Date클래스는 JDK 1.0때 만들어졌고, Calendar클래스는 JDK1.1에 만들어졌다.
  • java.util 패키지 안에 존재한다.
  • Date는 지역화에 대한 부분이 고려되지 않았다.
    • 지역화란, 지역에 따라서 시간, 통화(원, 달러, 엔 등) 언어등에 대하여 고려하는 프로그래밍을 지역화에 맞춘 프로그래밍이라고 합니다.
  • Date클래스를 보면 대부분의 생성자와 메소드가 Deprecated되어 있다.
    • Deprecated된 것은 앞으로 지원을 안하거나 문제가 있을 수 있으니 사용하지 말라는 뜻입니다.
  • 기본 생성자를 이용한 Date클래스 생성
    • 기본 생성자로 Date인스턴스를 만들게 되면 현재 시간과 날짜 정보를 Date인스턴스가 가지게 됩니다.
    • Date date = new Date();
  • toString()메소드를 이용하여 현재 시간을 문자열로 구합니다.
    • 출력 결과 : Wed Jan 06 18:36:56 KST 2016
    • System.out.println(date.toString());
  • 원하는 형태로 출력하기 위해 java.util.SimpleDateFormat 클래스를 이용한다.
    • yyyy는 년, MM은 월, dd는 일을 표현한다.
    • hh는 시간, mm은 분, ss는 초를 표현하며 a는 오전/오후 를 표현한다.
    • zzz는 TimeZone을 나타낸다. 한국의 경우 한국표준시 KST가 TimeZone에 해당하는 값입니다.
  • 현재 시간을 Long값으로 구하는 방법
System.out.println(date.getTime()); // System이 가지고 있는 currentTimeMillis()메소드를 이용해도 됩니다.

long today = System.currentTimeMillis(); System.out.println(today);

 

사용예제

	public static void main(String[] args) {
    	// 현재시간 Date 생성
		Date date = new Date();
		// date 객체는 형변환 없이도 바로 출력이 가능하다.
		System.out.println(date.toString());	
		
		// SimpleDateFormat 이용해 출력형식 지정
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd a hh:mm:ss zzz");
		System.out.println(df.format(date)); // format은 String 객체 반환, 
	}

 

 

 

 

2. Calendar

Date가 가지는  단점을 해결하고 등장한 것이 Calendar클래스

  • Calendar 클래스 생생 방법
    • Calendar클래스는 인터페이스로 정의된 추상클래스이다.
    • Calendar클래스에 대한 인스턴스를 생성하려면 Calendar가 가지고 있는 클래스 메소드 getInstnace()를 사용해야 한다.
    • getInstance()메소드를 호출하면 내부적으로 java.util.GregorianCalendar 인스턴스를 만들어서 리턴한다.
    • GregorianCalendar는 Calendar의 자식 클래스이다. (음력, 유대력 등등 다양한 달력이 존재)
Calendar cal = Calendar.getInstance();

// 현재날짜에 원하는 만큼 연산이 가능
cal.add(Calendar.MONTH, 1);

// Date 객체에 담아 형식지정이 가능
date = cal.getTime();
System.out.println(new SimpleDateFormat("yyyy-MM-dd").format(date))
int yyyy = cal.get(Calendar.YEAR); 
int month = cal.get(Calendar.MONTH) + 1; // 월은 0부터 시작합니다. int date = cal.get(Calendar.DATE); 
int hour = cal.get(Calendar.HOUR_OF_DAY); 
int minute = cal.get(Calendar.MINUTE);

Calendar 클래스의 주요 상수 (get 메소드안에 해당상수를 사용)

상수 사용방법 설명
static int YEAR Calendar.YEAR 현재 년도
static int MONTH Calendar.MONTH 현재 월 (1월: 0)
static int DATE Calendar.DATE 현재 월의 날짜
static int WEEK_OF_YEAR Calendar.WEEK_OF_YEAR 현재 년도의 몇째 주
static int WEEK_OF_MONTH Calendar.WEEK_OF_MONTH 현재 월의 몇째 주
static int DAY_OF_YEAR Calendar.DAY_OF_YEAR 현재 년도의 날짜
static int DAY_OF_MONTH Calendar.DAY_OF_MONTH 현재 월의 날짜
static int DAY_OF_WEEK Calendar.DAY_OF_WEEK 현재 요일(일요일:1 ,토요일: 7)
static int HOUR Calendar.HOUR 현재 시간 (12시간제)
static int HOUR_OF_DAY Calendar.HOUR_OF_DAY 현재 시간 (24시간제)
static int MINUTE Calendar.MINUTE 현재 분
static int SECOND Calendar.SECOND 현재 초

 

Calendar 클래스의 문제점

 

  • 불변 객체가 아니다

Date, Calendar 클래스는 set 메서드를 제공합니다. 날짜라는 특수성이 있지만, 불변객체가 아니기에 여러곳에서 공유 되었을때 원치 않는 결과값을 얻는 문제가 발생합니다.

  • int 상수 필드의 남용

cal.add(Calendar.DATE, 1); // 하루를 더함

 하루는 더하는 계산이지만, cal.add(Calendar.DECEMBER, 1) 이라는 값이 와도 컴파일 과정에서 오류를 잡을 수 없습니다.

  • 헷갈리는 월 지정

cal.set(2020, 8, 30); // 2020-09-30

2020-08-30 일을 출력을 기대하였지만, Calendar 월의 상수값은 0부터 시작합니다.

  • 일관성 없는 요일 상수

// 2020-08-30 SUNDAY
cal.get(Calendar.DAY_OF_WEEK); // 1
Date date = cal.getTime();
date.getDay(); // 0

Calendar 일요일 상수값은 1,  Date 일요일 상수값은 0 입니다.

  • 오류에 둔감한 timezone id 지정

TimeZone zone = TimeZone.getTimeZone("Asia/Seoul"); // Asia/Seoul
zone.getID();
TimeZone testZone = TimeZone.getTimeZone("Seoul/Asia");
testZone.getID(); // GMT

Time Zone ID에 Seoul/Asia는 존재하지 않지만 오류는 발생하지 않습니다.

  • Java.util.Date의 하위 클래스 문제

eqauls 대칭성 문제가 있는데, 

하위 클래스 timestamp에 대하여 객체 a.equal(b) true인데 b.eqauls(a) false가 나오는 문제가 있습니다.

 

이외에도 다양한 문제들로 Thirdparty 라이브러리들이 이용되다가 1.8이후 time이라는 클래스가 나오게 되었습니다. 

 

 

 

 

 

3. java.time 패키지

 

 LocalDate, LocalTime, LocalDateTime이 있습니다.

각각 날짜와 시간을 위해 사용되는 클래스입니다.

Local이라는 단어에서 알 수 있듯이 , 지역화 되지 않은 제한적인 지역의 날짜를 가지는 클래스입니다.

 

  • LocalDate 날짜 클래스
LocalDate curDate = LocalDate.now(); // 2020-08-30
LocalDate targetDate = LocalDate.of(2020, 8, 30); // 2020-08-30

캘린더에서와 다르게 month의 상수값은 우리가 사용하는 달력과 일치합니다.

 

  • LocalTime 시간 클래스
LocalTime curTime = LocalTime.now(); // 22:09.02.831
LocalTime targetTime = LocalTime.of(22, 8, 30); // 22:08:30 인자를 4개까지 쓸 수 있는데 nano 시간

 

시간클래스이고, 매우 직관적입니다.

 

  • LocalDateTime 날짜 + 시간 클래스

 

LocalDateTime curDateTime = LocalDateTime.now();

LocalDate curDate = LocalDate.now();
LocalTime curTime = LocalTime.now();
LocalDateTime targetDateTime = LocalDateTime.of(curDate, curTime);

System.out.println(curDateTime); // 2020-08-30T22:12:43.946
System.out.println(targetDateTime); // 2020-08-30T22:12:43.946

날짜와 시간을 모두 표현하고 싶으면 LocalDateTime을 이용하시면 됩니다. 

 

형변환

Date 클래스는 형식 지정을 위해 SimpleDateFormat 클래스를 사용했지만

LocalDateTimeDateTimeFormatter라는 클래스를 이용해 형식을 지정합니다.

, LocalDateTime에서  format이라는 메소드는 DateTimeFormatter 형식을 받아, String으로 반환합니다.

System.out.println(curDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

 

 

샘플코드

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

public class DateTimeExam {
	public static void main(String[] args) {
		LocalDate curDate = LocalDate.now();		// now로 지금시간 받거나
		LocalTime curTime = LocalTime.of(12,12,12);	// of로 지정값을 받을수 있다.
		LocalDateTime DateTime = LocalDateTime.of(curDate, curTime);	// 날짜, 시간을 넣어서 셋팅했다
		
		System.out.println(curDate);
		System.out.println(curTime);
		System.out.println(DateTime+"\n");
		
		System.out.println(DateTime.toLocalDate());
		System.out.println(DateTime.toLocalTime());
		System.out.println(DateTime.getYear() +"년 "+ DateTime.getMonthValue()+"월 "+DateTime.getDayOfMonth()+"일 \n");
		
		System.out.println(DateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd a hh:mm:ss ")));
	}
}

 

 

 

챔쥬

https://java119.tistory.com/52