시간관련 패키지 & 클래스

java.util - Date, Calendar

  • Date는 JDK1.0, Calendar는 JDK1.1 부터 제공되었다.
  • Calendar는 추상클래스라서 객체를 직접 생성할 수 없고, 메소드를 통해서 완전히 구현된 클래스의 인스턴스를 얻어야 한다.
    Calendar cal = Calendar.getInstance();
  • getInstance()가 static인 이유
    • 메소드 내의 코드에서 인스턴스 변수를 사용하거나 인스턴스 메소드를 호출하지 않기 때문
    • static이 아니라면 객체를 생성한 다음에 호출해야 하는데 Calendar는 추상클래스라 객체를 생성할 수 없기 때문

Calendar 와 Date 간 변환

  • Calendar가 추가되면서 Date는 대부분의 메소드가 deprecated 되었다.
    //1. Calendar를 Date로 변환
        Calendar cal = Calendar.getInstance();
          ...
        Date d = **new** Date(cal.getTimeInMillis());
    
    //2. Date를 Calendar로 변환
        Date d = **new** Date();
          ...
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
  • get(Calendar.MONTH)로 얻어오는 값은 1~12가 아니라 0~11이다. 그래서 0이 1월 11이 12월을 의미한다.

두 날짜간의 차이 구하기

  • 두 날짜를 최소단위인 초단위로 변경한 다음 그 차이를 구한다.

시간상의 전후

  • 두 날짜간의 차이가 양수인지 음수인지 판단
  • boolean after(Object when) 또는 boolean before(Object when) 사용

특정 날짜/시간 기준 일정 기간 전후의 날짜/시간 알기

  • add(int field, int amount)
  • roll(int field, int amount)
    • add()와의 차이점은 다른 필드에 영향 미치지 않음
    • 단, Calendar.DATE가 말일일 때, roll로 Calendar.MONTH를 변경하면 Calendar.DATE 필드에 영향을 미친다.

해당 월의 마지막날 알기

  • 다음 달의 1일에서 하루 빼기
  • getActualMaximum(Calendar.DATE) 사용

일 수 계산

  • Calendar는 1970년 1월 1일을 기준으로 계산
  • 1970년 1월 1일 이전에 날짜에 대해 getTimeInMillis()를 호출하면 음수 반환

java.time 패키지

Java의 탄생과 함께한 Date와 Calendar의 단점을 해소하기 위해JDK 1.8부터 java.time 패키지가 추가되었다.이 패키지는 4개의 하위 패키지가 있다.

**java.time** - 날짜와 시간을 다루는데 필요한 핵심 클래스들 제공

  • java.time.chrono - 표준(ISO)이 아닌 달력 시스템을 위한 클래스들 제공
  • java.time.format - 날짜와 시간을 파싱, 형식화하기 위한 클래스들 제공
  • java.time.temporal - 날짜와 시간의 필드와 단위(unit)을 위한 클래스들 제공
  • java.time.zone - 시간대(time-zone)와 관련된 클래스들 제공

java.time 패키지의 클래스들은 String 클래스처럼 Immutable이다. 즉, 날짜나 시간을 변경하면 기존의 객체가 변경되는 것이 아니라, 새로운 객체를 반환한다.(Thread-Safe)

java.time 패키지의 핵심 클래스

시간 표현 ⇒  LocalTime

날짜 표현 ⇒  LocalDate

시간 + 날짜 표현 ⇒  LocalDateTime

Timezone + 시간 + 날짜 표현 ⇒ ZonedDateTime

날짜, 시간 객체(LocalDate, LocalTime) 생성하기

java.time 패키지에 속한 클래스의 객체 생성은 now()와 of()로 한다.

  • now() ⇒
    
    LocalDate date = LocalDate.now();
    LocalTime time = LocalTime.now();
  • of() ⇒
    
    LocalDate date = LocalDate.of(2022, 12, 16); // 2022년 12월 16일
    LocalTime time = LocalTime.of(23, 59, 59); // 23시 59분 59초

타임스탬프(time-stamp)

  • 날짜와 시간을 초단위로 표현한 값
  • 날짜와 시간을 하나의 정수(Long)로 표현할 수 있어서 날짜와 시간의 차이를 계산하거나 순서를 비교하는데 유리하다.
    
    Timestamp.valueOf(LocalDateTime.now());
    Timestamp.valueOf(LocalDateTime.now()).getTime();
    
    Timestamp.valueOf(LocalDateTime.now()) = 2022-12-18 21:27:04.730605
    
    Timestamp.valueOf(LocalDateTime.now()).getTime() = 1671366424953

필드 값 변경하기

날짜와 시간에서 특정 필드 값을 변경하려면 with로 시작하는 메소드 사용

  • 종류
    
    LocalDate withYear(int year)  
    LocalDate withMonth(int month)  
    LocalDate withDayOfMonth(int dayOfMonth)  
    LocalDate withDayOfYear(int dayOfYear)  
    
    LocalTime withHour(int hour)  
    LocalTime withMinute(int minute)  
    LocalTime withSecond(int second)  
    LocalTime withNano(int nanoOfSecond)
  • with() 사용시 원하는 필드를 직접 지정 가능
    LocalDate with(TemporalField field, **long** newValue)
  • 필드를 변경하는 메소드들은 항상 새로운 객체를 생성해서 반환하므로 대입연산자를 같이 사용
    
    date = date.withYear(2018); 
    time = time.withHour(12); 
  • LocalTime의 truncatedTo()는 지정된 것보다 작은 단위의 필드를 0으로 만든다.
    
    LocalTime time = LocalTime.of(12, 34, 56); // 12시 34분 56초
    time = time.truncatedTo(ChronoUnit.HOURS); // 시(hour)보다 작은 단위를 0
    System.out.println(time); // 12:00

날짜와 시간 비교

  • compareTo() : 같으면 0, date1이 이전이면 -1, 이후면 1
    
    int result = date1.compareTo(date2);
    
  • boolean형 메소드들
    
    boolean isAfter (ChronoLocalDate other)
    boolean isBefore (ChronoLocalDate other)
    boolean isEqual (ChronoLocalDate other)

LocalDateTime

  • LocalDate와 LocalTime을 합쳐서 LocalDateTime을 만들 수 있다.
    
    LocalDate date = LocalDate.of(2018, 10, 05);
    LocalTime time = LocalTime.of(12,34,56);
    
    LocalDateTime dt = LocalDateTime.of(date, time);
    LocalDateTime dt2 = date.atTime(time);
    LocalDateTime dt3 = time.atDate(date);
    LocalDateTime dt4 = date.atTime(12, 34 ,56);
    LocalDateTime dt5 = time.atDate(LocalDate.of(2018, 10, 05));
    LocalDateTime dt6 = date.atStartOfDay(); // = date.atTime(0,0,0);
    
    LocalDateTime dateTime = LocalDateTime.of(2018, 10, 05, 12, 34, 56);
    LocalDateTime today = LocalDateTime.now();
  • LocalDateTime을 LocalDate 또는 LocalTime으로 변환할 수 있다.
    
    LocalDateTime dt = LocalDateTime.of(2018, 10, 05, 12, 34, 56);
    LocalDate date = dt.toLocalDate();
    LocalTime time = dt.toLocalTime();

Period와 Duration

  • 두 날짜의 차이를 나타내는 Period는 between()으로 얻을 수 있다.
    
    LocalDate date1 = LocalDate.of(2022, 12, 16);
    LocalDate date2 = LocalDate.of(2023, 1, 1);
    
    Period pe = Period.between(date1, date2);
  • until() 은 between()과 같은 역할이지만,between()은 static 메소드이고, until()은 인스턴스 메소드이다
    
    long sec = LocalTime.now().until(endTime, ChronoUnit.SECONDS);
  • LocalDate의 toEpochDay() 는 Epoch Day인 1970-01-01부터 날짜를 세어서 반환.Period를 사용하지 않고 두 날짜 사이의 일 수를 편하게 계산할 수 있다.
    
    LocalDate date1 = LocalDate.of(2022, 12, 16); 
    LocalDate date2 = LocalDate.of(2023, 1, 1); 
    long diff = date2.toEpochDay() - date1.toEpochDay();

출력형식 정의

  • DateTimeFormatter의 ofPattern()으로 원하는 출력형식을 작성할 수 있다.
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");

0개의 댓글