LocalDatetime 탐구하기
프로젝트를 진행하면서 영화 스케쥴을 등록하고 출력해야하는 작업이 필요했는데 이때 사용한 것이 Datetime 형이다
Oracle DB를 사용했고, 스프링 부트로 백엔드를 진행했으며 자바스크립트로 프론트엔드 작업을 했는데 이때 어떻게 사용했는지 정리하고자 한다.
Oracle에서는 Date type으로 저장했고 이때 DB에서 만약 시간이 보이지 않는다면
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
명령문을 실행하면 시간도 같이 보인다.
-sql
CREATE TABLE Schedule ( schecode number(10) primary key, mcode number(7) not null, hcode number(10) not null, scdate date not null, -- 날짜, 시간까지 같이 저장할 것 constraint fk_Schedule_mcode foreign key(mcode) references Movie (mcode), constraint fk_Schedule_hcode foreign key(hcode) references Hall (hcode) ); |
Entity에서는 format을 지정해줬다.
Oracle 에서 직접 데이터를 넣을때 이런 패턴으로 들어가기 때문에 동일하게 해주면 된다.
예시) insert into schedule(schecode, mcode, hcode, scdate) values (seq_schedule.nextval, 64, 46, TO_DATE('2022/03/14 21:00:00','YYYY-MM-DD HH24:MI:SS'));
-Entity
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime scdate;
DTO가 중요한데 DTO를 통해 프론트에서 받은 데이터는 String 형태일것이므로 이것을 Datetime으로 맞춰주는게 어려웠다. 이때 사용하는 것이 ISO.Date_time
-DTO
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private LocalDateTime scdate;
프론트에서 해당 날짜, 시간을 입력할때는 input태그를 type=datetime-local 로 설정해주면 form 태그 전송방식으로 문제없이 전달된다.
-html
<input id="scheduleDate" type="datetime-local" class="form-control" name="scdate" onchange="checkDate(this.value)">
만약 스케쥴을 날짜로 찾고 싶을때 프론트에서 전달된 string date(2022-04-13 형태임)를 백엔드에서 변경해서 사용할 수 있는데 다음과 같이 변경해주었다.
@GetMapping("/Schedule")
public List<ScheduleDTO> scheduleDTOList(@RequestParam("tcode") Long tcode,
@RequestParam("newschdate") String schedate){
LocalDateTime newschedate=LocalDateTime.parse(schedate+"T00:00:00", DateTimeFormatter.ISO_DATE_TIME);
List<ScheduleDTO> scheduleDTOList=userScheduleService.findbyDate(tcode, newschedate);
return scheduleDTOList;
}
+) 추가로 스케쥴 데이터를 insert할때 이미 같은 시간에 스케쥴이 존재하는지 여부를 확인하여 만약 같은 시간에 스케쥴이 존재하면 튕겨내는 스크립트를 작성하고 싶었는데 형태가 같다면 단순한 비교문으로 datetime을 비교할 수 있다.
해당 장소(여기서는 홀, hcode) 에 스케쥴이 있는지 ajax로 스케쥴 리스트를 불러와서 해당 시간과 내가 선택한 시간(input의 type=datetime-local임) 을 비교문으로 비교했다.
//선택한 홀과 시간에 스케쥴이 이미 있는지 없는지 체크하는 스크립트 추가
// 홀을 선택하면 홀에 대한 스케쥴을 가져옴
function findSchedule(hcode){
console.log(hcode)
$.ajax({
url: "/findSchedule",
data: { hcode: hcode },
type: "POST",
dataType: "json"
})
.done(function(res) {
scheduleList=res;
})
.fail(function(xhr, status, errorThrown) {
console.log(xhr)
console.log(status)
})
}
// 만약 과거날짜를 선택할 경우 선택 불가하게 만들기
// hall 정보 따라 가져온 스케쥴과 지금 선택한 날짜와 비교해서 이미 동시간에 스케쥴이 존재하는 경우 alert
let today=new Date()
let scheduleDate=document.querySelector('#scheduleDate')
let scheduleList=new Array();
function checkDate(selDate){
let changeDate=new Date(selDate)
console.log(changeDate)
console.log(scheduleList)
if(changeDate < today) {
alert("오늘 이전의 날짜는 선택할 수 없습니다.")
scheduleDate.value=""
}
scheduleList.forEach(schedule=>{
let scdate=new Date(schedule.scdate)
let enddate=new Date(schedule.enddate)
console.log(scdate)
console.log(enddate)
if(changeDate>=scdate && changeDate<=enddate){
alert(`이미 선택한 시간에 스케쥴이 존재합니다. \n 스케쥴 코드: ${schedule.schecode}\n 영화제목: ${schedule.movieDTO.titleKo}\n 시작시간: ${schedule.scdate} \n 종료시간: ${schedule.enddate} `)
scheduleDate.value=""
}
})
}
이 스크립트를 작성할때 헷갈렸던 부분은 데이터에서 뽑아낸 localdatetime이 프론트에서는 string이라는 점에서 좀 해맸다.
schedule의 scdate를 스크립트에서도 Date로 선언해서 형을 변경해서 사용해야 자바스크립트에서 같은 모양으로 인식하고 비교문이 실행된다.