[Java] 날짜 및 시간 조작

INO·2022년 3월 26일
1
post-thumbnail

날짜 및 시간을 다루는 클래스

  • java.util.Date
  • java.util.Calendar
  • java.text.SimpleDateFormat

현재 날짜를 위한 조작

Date now = new Date();

Date 클래스로 인스턴스를 생성하면 해당 객체가 생성될 때의 날짜와 시간이 인스턴스에 저장됩니다.

날짜 데이터 변경할 때

Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, 1);

Date nextMonth = cal.getTime();

Calendar는 프로그래머가 임의로 인스턴스를 만들지 못하게 합니다. 그래서 getInstance() 메서드를 사용하여 객체를 생성할 수 있습니다.

  • 임의로 인스턴스를 만들지 못하게 하는 것은 디자인 패턴 중의 하나인 싱글톤 패턴입니다. 많이 사용되는 디자인 패턴입니다.

Calendar는 add 메서드를 사용하여 데이터 값을 변경하게 합니다. 첫번째 인수로는 Calendar 클래스의 상수를 두번째 인수로 변동할 양을 지정

  • 두번째 인수로 마이너스도 가능합니다.

Calendar 클래스의 주요 상수

  • YEAR : 연
  • MONTH : 월
  • DATE : 일
  • DAY_OF_MONTH : 일(DATE와 동일)
  • HOUR_OF_DAY : 24시간제의 시간
  • HOUR : 12시간제의 시간
  • MINUTE : 분
  • SECOND : 초
  • MILLISECOND : 밀리초

지정 날짜로 세팅할 때

Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 1);

Date specificTime = cal.getTime();

set 메서드의 첫번째 인수에 해당 하는 값이 변경되고 나머지는 현재의 시간에서 참조해오게 된다.

  • set은 특정 값으로 변경하는 것이기 때문에 마이너스 값을 허용하지 않습니다.

날짜에서 특정 항목을 추출할 때

Date specificTime = cal.getTime();
int month = cal.get(Calendar.MONTH);

날짜에서 월만을 얻어올 때 사용하는 방법입니다. 하지만 get()은 월을 가져올 때는 -1을 한 값을 가져오므로 월을 사용할 떄는 1을 더해준 후 반환해야 할 것입니다.

  • 나머지의 데이터는 모두 1부터 시작해서 반환합니다.

날짜 데이터를 지정 서식으롤 출력할 때

Date specificTime = cal.getTime():

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");

String formatedStr = sdf.format(specficTime);

SimpleDateFormat 클래스의 생성자에 문자열로 된 서식을 넣고 formate 메서드의 인수로 Date 클래스를 넣어주면 해당 형식으로 문자열을 변경할 수 있습니다.

SimpleDateFormat의 서식

  • yyyy : 연도
  • yy : 연도
  • MM : 월
  • dd : 일
  • HH : 시
  • mm : 분
  • ss : 초
  • SSS : 밀리초

날짜 데이터를 비교할 때

날짜 데이터를 비교할 떄는 Calendar 클래스의 compareTom 메서드를 사용합니다.

Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();

cal1.set(Calendar.DAY_OF_MONTH, 1);
cal2.set(Calendar.DAY_OF_MONTH, 2);

int result = cal1.compareTom(cal2);

위 코드의 결과는 -1로 값이 비교 값이 작을 때 반환 받습니다. 만약 같을 경우 0을, 클 경우 1을 반환합니다.

compareTo와 유사한 메서드

  • after : 비교할 인스턴스가 미래인지 비교한다.
  • before : 비교할 인스턴스가 과거인지 비교한다.
  • eqauls : 비교할 인스턴스가 비교 대상과 같은지 판정한다.
  • compareTo : 비교할 인스턴스가 비교 대상보다 미래면 1, 과거면 -1, 같으면 0을 반환한다.

Date-Time API

Java 8에서 Date-Time Api가 추가되었습니다. Date-Time Api는 이전 자바의 날짜 다루는 클래스에서 부족했던 기능을 보완하여 제공됩니다.

Date-Time Api는 시차에 관한 어플리케이션의 경우 떠욱 유용합니다. 시차만을 다를 뿐 아니라 서머타임 등 시간에 관계된 규칙을 다룰 수 있습니다.

  • 물론 Calendar나 Date 클래스도 시차를 다룰 수 있지만 더욱 용이하고 세밀하게 시차를 다룰 수 있게 되었습니다.

Date-Time Api의 맞는 클래스를 고르는 방법은 아래와 같습니다.
1. 시차를 다루지 않으면 Local로 시작하는 클래스를 사용한다.
2. 시차를 다루면 Offset으로 시작되는 클래스를 사용한다.
3. 시차뿐만 아니라 그 지역의 일시가 고려된 편이 바람직하면 ZonedDateTime을 사용한다.

// 시차 X 
LocalDateTime localDateTime = LocalDateTime.now();
// 시차 O 
OffsetDateTime offsetDateTime = OffsetDateTime.of(2022, Month.MARCH.getValue(), 26, 20, 30, 30, 0, ZoneOffset.of("+09:00"));
// 시차 O, 지역 정보 O
        ZonedDateTime zonedDateTime = ZonedDateTime.parse("2022-03-26T20:30+09:00[Asia/Seoul]");

LocalDateTime은 new를 사용하여 객체를 생성할 수 없습니다. 반드시 static 메서드를 사용하여 생성해야 하니다. now 외에도 of를 사용하여 생성하는 등 여러 방법이 있습니다.

기간

기간을 다루는 클래스는 2가지가 있습니다.
1. Period : 날짜의 간격을 다루는 클래스
2. Duration : 시간의 간격을 다루는 클래스

Period period = Period.between(localDateTime1.toLocalDate(), localDateTime2.toLocalDate());
period.getYears(); // 연차
period.getMonth(); // 월차
period.getDays(); // 일차
period.toTotalMonths(); // 누적

Duration duration = Duration.between(localDateTime1, localDateTime2);
duration.getNano(); // 나노차
duration.toDays(); // 일차
duration.toHours(); // 시간차
duration.toMinutes(); // 분차
duration.getSeconds(); // 초치
duration.toMillis(); // 밀리초차
duration.toNanos(); // 나노차

Period와 Duration은 오무 between 메서드를 사용하여 기간을 구합니다.

  • 두 클래스 모두 plus와 minus 메서드를 사용해 산출한 기간을 날짜와 시간을 임의로 변경할 수 있습니다.

Date-Time Api의 Date, Calendar 클래스 지원

지금까지의 많은 어프릴케이션들은 Calendar와 Date 클래스를 사용합니다. 그런 시스템에서 Date-Time을 사용하려면 Calendar와 Date로 변환해야 합니다. 그래서 Date-Time은 Instant 클래스를 사용하여 변환할 수 있도록 지원합니다.

Instant instant = localDateTime.toInstant(ZoneOffset.of("+09:00"));
Date date = Date.from(instant);

Date-Time Api는 나노초까지 셀 수 있지만 Calendar와 Date클래스는 밀리촊따지 셀 수 있으므로 변환할 때 데이터 유실이 발생하지 않는지 주의해야 합니다.

profile
🎢

0개의 댓글