minlog
article thumbnail

 

LocalDateTime · LocalDate · DateTimeFormatter · Period

 

여행 계획을 세워서 공유하는 것이 이번 프로젝트의 주요한 로직입니다.
날짜 관련되어 기능들이 많이 필요할 것 같아서  로직을 구현 할때 사용할 수 있는 객체들을 정리하며 작업해보았습니다.
 
 

 

0. 적용한 로직 : DAY 날짜 계산하기

먼저 계획을 작성할때,  출발일과 종료일을 받아서 세부 일정을 입력한 날짜에 맞게 계획 할 수 있도록,
DAY 를 계산하는 로직을 추가했습니다.

※ 추후에 현제 날짜와 비교하여 노출하는 로직도 추가할 예정입니다.

1) Controller

📑 TravelController.java

@PostMapping("/category")
public String categorySave(@ModelAttribute("category") CategoryDTO categoryDTO,Model model) {
    log.info(categoryDTO); 
    
    //1. d-day계산 로직
    int days = categoryService.categoryDays(categoryDTO.getDateStart(), categoryDTO.getDateEnd());
    
    int[] arr = new int[days]; // 2. 가져온 d-day 를 배열로 변경
    
    model.addAttribute("category",categoryDTO);
    model.addAttribute("days",arr); // 3. 화면에 전달
    return "travel/travelMap";
}

 

2) Service

📑 CategoryService.java

public interface CategoryService {
    boolean categorySave(CategoryDTO categoryDTO);
    int categoryDays(String start, String end); // D-day 구하는 로직
}

 
📑 CategoryServiceImpl.java

@Override
public int categoryDays(String start, String end) {
    log.info("D-day 계산");

    // 1. 포맷터 생성
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

    // 2. 문자열 : 날짜만 받아오고 있으므로 임의의 시간을 추가
    start = start + " 00:00:00.000";
    end = end + " 00:00:00.000";

	// 3. 포맷터를 활용하여 문자열을 LocalDateTime 타입으로 변환
    LocalDateTime startDate = LocalDateTime.parse(start, formatter);
    LocalDateTime endDate = LocalDateTime.parse(end, formatter);

    // 4. 출발일과 종료일을 비교
    Period period = Period.between(LocalDate.from(startDate), LocalDate.from(endDate));
    
    // 5. 일 차이가져옴 ( 출발일 - 종료일 ) 
    	//ex. 26 - 30
    int days = period.getDays();
    log.info(days); // ex.4
    
    // 6. 하루 추가시켜 줌 ( ex.5 )
    days = days + 1;  

    log.info("days : {}",days);
    return days;
}

 

3 ) 타임리프 화면 

each 를 활용해 개수만큼 <option> 태그를 생성한다.
📑navBarTravelMap.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layout/basic}">
<th:block th:fragment="navBarTravelMap">
  <div class="navbar">
    
        ...

              <h4 class="mt-4 pt-4 border-top"><i class="bi bi-calendar-check-fill"></i>
                일정선택</h4>
              <p class="txt_info mt-1">※ 일정을 완성하면 저장을 꼭 눌러주세요!</p>
              <div class="day_select flex-column flex-lg-row mt-3" style="display: flex;">
                <select class="form-select" aria-label="Default select example">
                  <th:block th:each="list, i : ${days}">
                    <option th:text="|D -${i.index + 1}|" th:value="${i.index + 1}"></option>
                  </th:block>
                </select>
        ...
</th:block>
</html>

 


 

1. LocalDateTime

날짜와 시간 정보가 필요할 때 사용됩니다.
LocalDateTime 을 사용하여 시간과 날짜를 구하면, 2023-06-24T11:44:30.327959 형식으로 구해집니다.
 

1) 현제 날짜와 시간 구하기

LocalDateTime now = LocalDateTime.now();

 

2) 년 / 월 / 주 / 일 조회 

LocalDateTime now = LocalDateTime.now();
System.out.println("getYear() = " + now.getYear());
System.out.println("getMonth() = " + now.getMonth());
System.out.println("getDayOfMonth() = " + now.getDayOfMonth());
System.out.println("getDayOfWeek() = " + now.getDayOfWeek());
System.out.println("getDayOfYear() = " + now.getDayOfYear());

 

3) 시간 / 분 / 초  조회 

LocalDateTime now = LocalDateTime.now();
System.out.println("getHour() = " + now.getHour());
System.out.println("getMinute() = " + now.getMinute());
System.out.println("getSecond() = " + now.getSecond());
System.out.println("getNano() = " + now.getNano());

 

4) 연산하기 

pluse  더하기 +  / minus 빼기 -    : 매개 변수 값 만큼 증가 또는 감소 합니다.

LocalDateTime now = LocalDateTime.of(2023, 6, 6, 10, 0, 0);
System.out.println("plusYears(3) = " + now.plusYears(3));
System.out.println("plusMonths(3) = " + now.plusMonths(3));
System.out.println("plusDays(3) = " + now.plusDays(3));
System.out.println("plusHours(3) = " + now.plusHours(3));
System.out.println("plusMinutes(3) = " + now.plusMinutes(3));
System.out.println("plusSeconds(3) = " + now.plusSeconds(3));

System.out.println("minusYears(3) = " + now.minusYears(3));
System.out.println("minusMonths(3) = " + now.minusMonths(3));
System.out.println("minusDays(3) = " + now.minusDays(3));
System.out.println("minusHours(3) = " + now.minusHours(3));
System.out.println("minusMinutes(3) = " + now.minusMinutes(3));
System.out.println("minusSeconds(3) = " + now.minusSeconds(3));

 

5) 비교하기

  • isAfter() - 인자보다 미래 시간이라면 true 반환
  • isBefore() - 인자보다 과거 시간이면 true 반환
  • isEqual() - 인자와 같은 시간이면 true 반환
  • compareTo()
    • compareTo() > 0 : 인자보다 미래 시간
    • compareTo() < 0 : 인자보다 과거 시간
    • compareTo() == : 인자와 같은 시간
// localDateTime1: 2023년 6월 1일 0시 0분 0초
LocalDateTime localDateTime1 = LocalDateTime.of(2023, 1, 1, 0, 0, 0);
// localDateTime2: 2023년 6월 1일 0시 0분 0초
LocalDateTime localDateTime2 = LocalDateTime.of(2023, 1, 1, 0, 0, 0);
// localDateTime3: 2024년 6월 1일 0시 0분 0초
LocalDateTime localDateTime3 = LocalDateTime.of(2024, 1, 1, 0, 0, 0);

 

6) LocalDateTime   >    LocalDate 로 변환

(  2023-06-24T11:44:30.327959  >  2023-06-24  )
toLocalDate() 메서드를 사용하여 객체 타입을 변환 할 수 있습니다.

LocalDateTime localDateTime = LocalDateTime.now();
localDateTime.toLocalDate()

 

7) LocalDateTime .pasrse(  )  ,  문자열 변환 확인 또는 포멧 변경

  • pasrse(String)
    •  한개의 매개 변수 문자열이 전달되는 경우 " yyyy-MM-dd " 형식을 사용하여 문자열을 날짜로 변환이 가능한지 분석합니다.  형식이 다른 문자열이 전달될 시  DateTimeParseException 이 발생
  • pasrse(String,DataTimeFormatter)
    • 문자열과 DataTimeFormatter 전달하면 포멧에서 변경한 형식으로 변환됩니다.
String str = "2023-06-05 13:47:13.248";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
System.out.println(dateTime);

 


 

2. LocalDate    

로컬 날짜 클래스로 날짜 정보만 필요할 때 사용한다. (시간은  LocalTime 클래스를 통해 따로 구할 수 있다.)
 

1) 현제 날짜

LocalDateTime.now()

 

2) LocalDate .of( ) 메서드를 사용한 날짜 개체 생성

LocalDate birthDay = LocalDate.of(1982, 02, 19);
System.out.println(birthDay );

 

3)  년 / 월 / 주 / 일 조회 

LocalDate today = LocalDate.now();

System.out.println(today.getYear() + " :  년");
System.out.println(today.getMonth() + " : 월을 문자로 반환");   
System.out.println(today.getMonthValue() + " : 월을 숫자로 반환");
System.out.println(today.getDayOfMonth() + " : 일");
System.out.println(today.getDayOfYear() + " : 객체의 일을 반환 (1~365, 윤년이면 366)";
System.out.println(today.getDayOfWeek() + " : 요일");

 

4) 날짜와 시간 객체의 비교

LocalDate와 LocalTime 클래스에도 객체를 비교할 수 있는 compareTo() 메소드가 오버라이딩되어 있습니다.

하지만 더욱 편리하게 날짜와 시간 객체를 서로 비교할 수 있도록 다음과 같은 메소드를 제공합니다.

  • isEqual() : 날짜만 비교
  • isBefore() : 두개의 날짜와 시간 객체를 비교하여 현제 객체가 명시된 객체보다 앞선 시간인지 비교
  • isAfter() : 두개의 날짜와 시간 객체를 비교하여 현제 객체가 명시된 객체보다 늦은 시간인지 비교
LocalDate today = LocalDate.now();   // 2023-06-24
LocalDate otherDay = LocalDate.of(2023, 06, 29);

System.out.println(today.compareTo(otherDay)); // - 5
System.out.println(today.isBefore(otherDay)); //true
System.out.println(today.isEqual(otherDay));  //false

 

5)  LocalDate  >  LocalDateTime 로 변환  

(   2023-06-24 > 2023-06-24T11:44:30.327959   )

LocalDate.from(LocalDateTime.now());

 
 


 

3. Period

두날짜 차이를 계산할 때 사용합니다.
 

1) between(LocalDate date1, LocalDate date2)

메서드를 통해 두 날짜의 차이를 구할 수 있습니다. 해당 메서드는 LocalDate 타입을 받습니다.

LocalDate startDate = LocalDate.now();  //현제 날짜
LocalDate endDate = LocalDate.of(2023,06,30); // 계산하려는 날짜

Period period = Period.between(startDate, endDate);

period.getYears();      // 년도 차이
period.getMonths();     // 개월 차이
period.getDays();       // 일 차이

 


 

4. DateTimeFormatter 

날짜, 시간 개채 포맷터 입니다.
이 클래스는 날짜와 시간을 구하기 위해 두가지 방법을 재공합니다.

  • 형식화 :  format(DateTimeFormatter formatter)
  • 파싱 :  parse(CharSequence text, DateTimeFormatter formatter).

 

1) 정의된 포맷터

더보기
Formatter Description Example
ofLocalizedDate(dateStyle) Formatter with date style from the locale '2011-12-03'
ofLocalizedTime(timeStyle) Formatter with time style from the locale '10:15:30'
ofLocalizedDateTime(dateTimeStyle) Formatter with a style for date and time from the locale '3 Jun 2008 11:05:30'
ofLocalizedDateTime(dateStyle,timeStyle) Formatter with date and time styles from the locale '3 Jun 2008 11:05'
BASIC_ISO_DATE Basic ISO date '20111203'
ISO_LOCAL_DATE ISO Local Date '2011-12-03'
ISO_OFFSET_DATE ISO Date with offset '2011-12-03+01:00'
ISO_DATE ISO Date with or without offset '2011-12-03+01:00'; '2011-12-03'
ISO_LOCAL_TIME Time without offset '10:15:30'
ISO_OFFSET_TIME Time with offset '10:15:30+01:00'
ISO_TIME Time with or without offset '10:15:30+01:00'; '10:15:30'
ISO_LOCAL_DATE_TIME ISO Local Date and Time '2011-12-03T10:15:30'
ISO_OFFSET_DATE_TIME Date Time with Offset 2011-12-03T10:15:30+01:00'
ISO_ZONED_DATE_TIME Zoned Date Time '2011-12-03T10:15:30+01:00[Europe/Paris]'
ISO_DATE_TIME Date and time with ZoneId '2011-12-03T10:15:30+01:00[Europe/Paris]'
ISO_ORDINAL_DATE Year and day of year '2012-337'
ISO_WEEK_DATE Year and Week 2012-W48-6'
ISO_INSTANT Date and Time of an Instant '2011-12-03T10:15:30Z'
RFC_1123_DATE_TIME RFC 1123 / RFC 822 'Tue, 3 Jun 2008 11:05:30 GMT'

 

 
 
 
 
 

profile

minlog

@jimin-log

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!