HTML time 입력: 시간 범위·15분 간격·초 단위 설정

HTML의 input type="time"은 하루 중 시각을 입력받습니다. 화면에 오전·오후가 표시되더라도 실제 값은 보통 09:30처럼 24시간제 문자열이며, 초가 있으면 13:10:20처럼 표현됩니다. min·max로 범위, 초 단위인 step으로 허용 간격을 지정합니다.

표시 형식과 value를 구분하기

입력 UI는 운영체제·브라우저·사용자 언어에 따라 다릅니다. 드롭다운이나 시각 선택 창이 항상 같은 모양으로 뜨는 것은 아닙니다. HTML의 초기값에는 오후 1시 30분 대신 13:30과 같은 유효한 시간 문자열을 넣으세요. 초기값은 value 속성, 사용자가 현재 선택한 값은 JavaScript의 input.value로 읽습니다.

time 값 자체에는 날짜나 시간대가 없습니다. 서울의 오전 9시인지 다른 지역의 오전 9시인지는 값만으로 알 수 없습니다. 예약처럼 실제 시점을 정해야 한다면 날짜와 기준 시간대도 함께 받아 서버에서 일관되게 해석해야 합니다. 90분 같은 소요 시간 입력에도 time을 그대로 사용하기보다 분 단위 숫자 등 목적에 맞는 형식을 선택하세요.

범위와 간격 설정하기

속성 설정 예시 의미
value 09:30 초기 시각입니다. 형식뿐 아니라 범위와 간격에도 맞아야 합니다.
min, max 09:00, 18:00 허용 시각의 경계입니다. 두 경계 자체도 범위에 포함됩니다.
step 900 900초, 즉 15분 간격입니다. 기본값 60은 1분이며, 1은 1초입니다.
required 불리언 속성 비어 있는 상태의 일반적인 폼 제출을 막습니다.
name meeting 폼에 포함할 항목 이름입니다. id만으로는 전송 이름이 생기지 않습니다.

간격은 유효한 min을 우선 기준으로 삼고, 없으면 유효한 HTML의 value, 그것도 없으면 자정부터 계산합니다. 예를 들어 min="09:00" step="900"이면 09:00·09:15·09:30이 유효하고 09:10은 간격에 맞지 않습니다. 실제 사용 가능한 예약 슬롯이나 휴무일을 판단해 주는 기능은 아니므로 서비스 규칙은 별도로 구현해야 합니다.

15분 간격과 초 단위 입력 전체 예제

다음 코드를 time.html로 저장해 브라우저에서 여세요. 별도 서버 없이 두 입력의 검증과 전송 값을 확인할 수 있습니다. 두 번째 입력은 초 단위 값을 허용하도록 step="1"을 명시합니다.

<!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>time 범위와 초 단위 입력</title>
  <style>
    body { margin: 24px; font-family: sans-serif; }
    label { display: block; margin: 16px 0 6px; }
    input { max-width: 100%; box-sizing: border-box; }
    pre { white-space: pre-wrap; overflow-wrap: anywhere; }
  </style>
</head>
<body>
  <h1>시각 선택</h1>
  <form id="demo">
    <label for="meeting">회의 시각 (09:00~18:00, 15분 간격)</label>
    <input id="meeting" name="meeting" type="time"
      min="09:00" max="18:00" step="900" value="09:30" required>
    <label for="checkpoint">점검 시각 (13:00~15:00, 1초 간격)</label>
    <input id="checkpoint" name="checkpoint" type="time"
      min="13:00:00" max="15:00:00" step="1" value="13:10:20" required>
    <p><button type="submit">전송 값 확인</button>
      <button type="reset">초기화</button></p>
  </form>
  <pre id="result" aria-live="polite"></pre>
  <script>
    const form = document.querySelector('#demo');
    const result = document.querySelector('#result');
    form.addEventListener('submit', (event) => {
      event.preventDefault();
      result.textContent = JSON.stringify([...new FormData(form).entries()], null, 2);
    });
    form.addEventListener('input', () => { result.textContent = ''; });
    form.addEventListener('reset', () => { result.textContent = ''; });
  </script>
</body>
</html>
  1. 처음에 전송 값 확인을 누르면 meeting은 09:30, checkpoint는 13:10:20입니다. 화면 표시가 오전·오후 방식이어도 결과 문자열은 24시간제로 나옵니다.
  2. 회의 시각을 08:45로 바꾸면 범위 검사에 걸립니다. 09:10은 범위 안이지만 15분 간격에 맞지 않아 제출이 막힙니다. 09:45로 바꾸면 제출할 수 있습니다.
  3. 회의 시각을 완전히 지우고 제출해 필수 입력 검사를 확인합니다. 다시 유효한 시각을 넣고 두 번째 입력의 초를 바꾸면 초 단위 결과를 비교할 수 있습니다.
  4. 점검 시각의 step="1"만 step="60"으로 바꾸어 다시 여세요. 기준 13:00:00에서 20초가 어긋난 초기값 13:10:20은 유효한 1분 간격이 아닙니다. 확인 후 step을 1로 복원하세요.
  5. 초기화를 누르면 회의 09:30, 점검 13:10:20으로 돌아갑니다.

자정을 넘는 범위와 서버 검증

time은 자정을 넘는 범위도 표현할 수 있습니다. 예를 들어 min="22:00" max="02:00"은 밤 10시부터 자정을 지나 새벽 2시까지의 시각을 의미합니다. 실제 날짜를 포함하는 구간은 아니므로 다음 날 날짜까지 자동으로 결정해 주지는 않습니다. 대상 브라우저에서 이 범위 검증이 동작하는지 확인하고 서버에서도 같은 규칙을 구현하세요.

브라우저의 선택창이나 검사 문구를 서버 검증의 대체 수단으로 삼으면 안 됩니다. 서버는 수신한 문자열의 형식, 범위, 간격을 다시 검사하고 필요한 날짜·시간대·예약 가능 여부와 조합해야 합니다. GET 방식의 URL에 보이는 %3A는 콜론을 URL 인코딩한 표현이며, 폼 값을 정상적으로 해석하면 다시 09:30 같은 문자열이 됩니다.

날짜도 받아야 한다면 date 입력의 날짜 값과 범위 설정을 함께 참고할 수 있습니다. 시각 형식과 속성 정의는 MDN time 입력 문서에서 확인할 수 있습니다.