フォームで「予約日」や「開始時刻」を入力してもらうとき、テキストボックスに自由入力させると表記がバラバラになりがちです。HTML には日付・時刻の専用入力欄が用意されていて、type 属性を変えるだけでカレンダーや時刻ピッカーが使えます。この記事では input type="date"・type="time"・type="datetime-local" の3つを中心に、値のフォーマット、入力範囲を絞る属性、JavaScript での値の取り出し方までをまとめます。初心者から中級者の方が、そのまま真似して動かせることを目標にしています。
目次
3つの入力欄でできること
type="date" は年月日を選ぶ入力欄、type="time" は時刻だけを選ぶ入力欄、type="datetime-local" は日付と時刻をまとめて選ぶ入力欄です。名前に local が付くのは、タイムゾーンを持たない「その場の日時」を扱うためで、実際にはブラウザやOSの言語設定に応じたカレンダーや時計のUIが表示されます。まずは3つを並べて、それぞれの見た目と選んだ値を確認してみましょう。下のデモは「選択内容を表示」ボタンで、各入力欄が持っている値を書き出します。
<form id="reserve">
<p>
<label for="d">日付</label>
<input type="date" id="d" name="d" value="2026-07-04">
</p>
<p>
<label for="t">時刻</label>
<input type="time" id="t" name="t" value="09:30">
</p>
<p>
<label for="dt">日時</label>
<input type="datetime-local" id="dt" name="dt">
</p>
<button type="button" id="show">選択内容を表示</button>
</form>
<div id="result" aria-live="polite"></div>
form p {
margin: 0 0 12px;
display: flex;
gap: 8px;
align-items: center;
}
label {
width: 3.5em;
}
button {
padding: 6px 14px;
cursor: pointer;
}
#result {
margin-top: 14px;
padding: 10px;
background: #f2f6ff;
border-radius: 6px;
min-height: 1.2em;
font-family: monospace;
white-space: pre-wrap;
}
const form = document.getElementById('reserve');
const result = document.getElementById('result');
document.getElementById('show').addEventListener('click', () => {
// input.value は表示言語に関係なく固定フォーマットの文字列
const date = form.d.value; // 例: "2026-07-04"
const time = form.t.value; // 例: "09:30"
const dt = form.dt.value; // 例: "2026-07-04T09:30"(未入力なら空文字)
// date 型なら valueAsDate で Date オブジェクトも取れる
const asDate = form.d.valueAsDate; // Date もしくは null
result.textContent =
'date : ' + date + '\n' +
'time : ' + time + '\n' +
'datetime-local: ' + (dt || '(未入力)') + '\n' +
'valueAsDate: ' + (asDate ? asDate.toISOString() : 'null');
});
value は言語設定に関係なく決まった書式になる
ここが最初に押さえておきたい大事な点です。カレンダーに表示される文字(「2026年7月4日」なのか「07/04/2026」なのか)はブラウザやOSの言語設定によって変わりますが、プログラムから読み取れる値は常に決まった書式の文字列です。つまり「見た目のローカライズ」と「実際の値」は別物で、開発者は表示のばらつきを気にせず一定の形式で値を受け取れます。各タイプの値の書式は次のとおりです。
| type | 値のフォーマット | 例 |
|---|---|---|
date | YYYY-MM-DD | 2026-07-04 |
time | HH:MM(秒があれば HH:MM:SS) | 09:30 / 09:30:15 |
datetime-local | YYYY-MM-DDTHH:MM | 2026-07-04T09:30 |
month | YYYY-MM | 2026-07 |
week | YYYY-Www(週番号) | 2026-W27 |
date と time の間の区切りが半角スペースではなく T である点、月・日・時・分がいずれもゼロ埋め2桁である点に注意してください。datetime-local の値にタイムゾーン情報(末尾の Z や +09:00)は含まれません。未入力のときはどのタイプも空文字("")を返します。上の表の month・week は年月や週を選ぶ入力欄で、サポートしていないブラウザではただのテキスト入力になります。
value 属性で初期値を入れておく
最初に表示する日付や時刻を決めておきたいときは、HTML の value 属性に上表と同じ書式の文字列を書きます。書式が少しでもずれていると初期値として反映されないので、必ずゼロ埋めした形で指定してください。
<!-- 初期値として 2026年7月4日 を表示 --> <input type="date" name="day" value="2026-07-04"> <!-- 初期値として 09:30 を表示 --> <input type="time" name="start" value="09:30"> <!-- 日付と時刻をまとめて初期化 --> <input type="datetime-local" name="at" value="2026-07-04T09:30">
min・max・step で入力できる範囲を絞る
「今日より前の日付は選べないようにしたい」「営業時間内だけ選ばせたい」といった制限は、min・max・step 属性で表現できます。それぞれの役割は次のとおりです。
| 属性 | 意味 |
|---|---|
min | 選択できる最小の日付・時刻。値と同じ書式で指定する |
max | 選択できる最大の日付・時刻。値と同じ書式で指定する |
step | 刻み幅。time と datetime-local は秒単位、date は日単位で指定する |
step は少しクセがあります。time や datetime-local では秒数で指定し、たとえば step="1800" なら30分刻み、step="900" なら15分刻みになります。既定では時刻の入力欄に秒は表示されませんが、step に60で割り切れない値(例: step="15")を指定すると秒のフィールドが現れます。逆に、秒を表示させたくないなら60の倍数にしておけば大丈夫です。date の step は日数で、step="7" とすると min を起点に1週間おきの日付だけを選べます。
次のデモは、来店日を今日以降に限定し、来店時刻を10:00〜18:00の30分刻みに絞った予約フォームです。両方の欄に required を付けているので、空のまま送信しようとするとブラウザが送信を止めて入力を促します。
<form id="booking">
<p>
<label for="day">来店日(今日以降)</label>
<input type="date" id="day" name="day" min="2026-07-04" required>
</p>
<p>
<label for="slot">来店時刻(10:00〜18:00 / 30分刻み)</label>
<input type="time" id="slot" name="slot"
min="10:00" max="18:00" step="1800" required>
</p>
<button type="submit">予約する</button>
</form>
<div id="msg" aria-live="polite"></div>
p { margin: 0 0 14px; }
label { display: block; margin-bottom: 4px; font-size: 14px; }
button { padding: 6px 16px; cursor: pointer; }
#msg { margin-top: 12px; color: #1a7f37; font-weight: bold; }
const form = document.getElementById('booking');
const msg = document.getElementById('msg');
form.addEventListener('submit', (e) => {
e.preventDefault(); // デモなので送信は止める
// required と min/max を満たさなければ submit 前にブラウザが弾く
msg.textContent =
form.day.value + ' の ' + form.slot.value + ' で予約を受け付けました。';
});
JavaScript で値を取り出す
入力された値を JavaScript で扱う基本は、要素の value プロパティを読むことです。返ってくるのは前述の書式に沿った文字列で、日付として計算したいときはそのままでは足し引きできません。そこで用意されているのが valueAsNumber と valueAsDate です。
valueAsNumber は値をミリ秒(1970年1月1日 UTC からの経過ミリ秒)で表した数値を返します。date なら深夜0時(UTC)を基準としたミリ秒、time なら0時からの経過ミリ秒になります。未入力のときは NaN です。一方 valueAsDate は date・month・week・time で使え、対応する Date オブジェクト(未入力なら null)を返します。ここで注意したいのは、datetime-local は valueAsDate をサポートしていない点で、null が返ります。datetime-local を Date にしたいときは valueAsNumber を使うか、value の文字列から自分で組み立てます。
const day = document.querySelector('input[type="date"]');
// 1. 文字列としてそのまま受け取る
console.log(day.value); // "2026-07-04"
// 2. ミリ秒(数値)として受け取る
console.log(day.valueAsNumber); // 例: 1783296000000 / 未入力なら NaN
// 3. Date オブジェクトとして受け取る
const d = day.valueAsDate; // Date もしくは null
if (d) {
d.setDate(d.getDate() + 7); // 1週間後を計算するなど
}
// 逆に JS から値を設定することもできる(書式は value と同じ)
day.value = "2026-12-31";
valueAsDate が返す Date は UTC 基準で作られる点も覚えておくと、getHours() などローカル時刻のメソッドを使ったときの数時間のズレに戸惑わずにすみます。単に入力値をサーバーへ送りたいだけなら、value の文字列をそのまま送るのが一番シンプルで確実です。
ブラウザによって見た目が変わることを前提にする
これらの入力欄のUIはブラウザやOSが用意しているため、カレンダーのデザインや時刻ピッカーの操作感、日付の表示順(年月日か月日年か)は環境ごとに異なります。デスクトップとスマートフォンでも見え方が変わり、スマートフォンではOS標準の日付・時刻ピッカーが開くのが一般的です。
大切なのは、見た目が違っても取得できる値は常に同じ固定書式だということです。ですから「表示のローカライズ」は環境任せにしておき、プログラム側は決まった書式の文字列を前提に処理を書けば、どの環境でも同じように動きます。細部のUIを自分で作り込みたい場合は自作のカレンダーライブラリを使う選択肢もありますが、まずは標準の入力欄で十分なケースが多いはずです。
まとめ
type="date"・type="time"・type="datetime-local" を使えば、日付や時刻の入力欄を type 属性だけで用意できます。値はそれぞれ YYYY-MM-DD、HH:MM、YYYY-MM-DDTHH:MM という固定書式の文字列で取得でき、表示のローカライズとは切り離して考えられます。min・max で範囲を絞り、step で刻み幅(時刻は秒数で指定、60の倍数なら秒は非表示)を、required で入力必須を、value で初期値を設定できます。JavaScript では value のほか、計算に便利な valueAsNumber と valueAsDate が使えます(ただし datetime-local の valueAsDate は非対応)。まずは標準の入力欄でフォームを組み立ててみてください。