Programming/Javascript

input type=datetime-local 최솟값 min, 현재값 value 적용하는 방법

Jan92 2021. 8. 8. 16:44

input type="datetime-local"

프로젝트 중 input을 통해 날짜 외 시간도 함께 받아 오는 것이 필요하여 input type="datetime-loacl"을 사용하였습니다.

그 과정에서 사용한 최솟값 min 설정, 현재값 value 설정 방법에 대해서 알아보겠습니다.

 

min, value를 설정하기 위해서는 YYYY-MM-DDTHH:mm:ss 형식의 시간이 필요합니다.

Javascript의 날짜와 시간은 Date 객체로 표현할 수 있는데요.

 

let nowDate = new Date();
console.log('nowDate : ' + nowDate);
// nowDate : Sun Aug 08 2021 11:22:13 GMT+0900 (한국 표준시)


let toISOStringDate = new Date().toISOString();
console.log('toISOStringDate : ' + toISOStringDate);
// toISOStringDate : 2021-08-08T02:22:13.141Z

 

new Date(); 를 통해 날짜를 생성했을 때는 현재 시간이 출력되지만, toISOSting() 메서드를 사용하게 되면 ISO 형식의 문자열을 반환하는 대신 UTC의 시간대로 반환되게 됩니다.

UTC 시간은 한국 시간과 9시간 차이가 나기 때문에 현재 시간을 사용하기 위해서는 그 차이를 계산하는 과정이 필요합니다.

 

console.log(new Date(new Date().toString().split('GMT')[0]+' UTC').toISOString());
// 2021-08-08T11:24:48.000Z

console.log(new Date(new Date().getTime() - new Date().getTimezoneOffset() * 60000).toISOString());
// 2021-08-08T11:24:48:893Z

UTC 시간으로 출력되는 ISO 형식의 문자열을 현재 시간으로 변환시키는 방법은 위 2가지가 있습니다.

 

 

두 번째 방법의 원리는 getTimezoneOffset() 함수를 살펴보면, 

The getTimezoneOffset() method returns the time zone difference. in minutes, from current locale (host system settings) to UTC.

 

즉, 로컬 시간에서 UTC까지의 차이를 구하여 분으로 반환하는데 이 반환값을 밀리초 단위를 인자로 받는 new Date() 함수에 적용하기 위해 1000(밀리초) * 60(초)를 곱해서 밀리초 단위로 만들어 빼는 것입니다.

 

<body>
    <div>
        <input type="datetime-local" id="dateTimeLocal">
    </div>

    <script>
        let dateElement = document.getElementById('dateTimeLocal');
        let date = new Date(new Date().getTime() - new Date().getTimezoneOffset() * 60000).toISOString().slice(0, -5);
        dateElement.value = date;
        dateElement.setAttribute("min", date);
    </script>
</body>

변환시킨 값을 현재 시간 value, min 값에 적용하는 최종 코드입니다.

 

* 변환시킨 값은 YYYY-MM-DDTHH:mm:ss.sssz 형식인데 적용시킬 값은 ss 까지만 필요하기 때문에 뒤에 .sssz .slice(0, -5)를 통해 제거하고 YYYY-MM-DDTHH:mm:ss 값만 사용합니다.

 

현재 시간은 .value 를 통해 적용하고, 최솟값은 setAttribute("min", value)를 통해 적용합니다.

 

 

min, value 적용 된 모습

 

min 값과 value 값이 적용 된 모습입니다.

 

 


저렇게 적용했을 때 문제점은 날짜 부분은 현재 날짜보다 이전의 날짜를 선택할 수 없도록 되어있지만 시간 부분은 현재 시간 이전의 날짜도 선택할 수 있다는 것이었습니다.

 

<body>
    <div class="m100">
        <h1>input datetime-local value, min, max</h1>
        <input type="datetime-local" id="dateTimeLocal" onchange="setMinValue()">
    </div>

    <script>
        let dateElement = document.getElementById('dateTimeLocal');
        let date = new Date(new Date().getTime() - new Date().getTimezoneOffset() * 60000).toISOString().slice(0, -5);
        dateElement.value = date;
        dateElement.setAttribute("min", date);

        function setMinValue() {
            if(dateElement.value < date) {
                alert('현재 시간보다 이전의 날짜는 설정할 수 없습니다.');
                dateElement.value = date;
            }
        }
    </script>
</body>

해당 문제를 해결하기 위해서 onchange() 함수를 사용하여 시간이 바뀌었을 때 바뀐 value 값과 이전 date 값을 비교하여 value 값이 이전이라면 alert을 띄우고 value=date; 로 적용시키는 function을 추가하였습니다.

 

 

현재 시간보다 이전의 날짜는 설정할 수 없습니다.