申請の「締切日」は時刻まで必要とは限りません。HTMLのinput type="date"から得た日付を、すぐDateへ変換して別のタイムゾーンで表示すると、元の日付と違って見える場合があります。日付だけの項目なら、まず日付の文字列として扱います。
ブラウザの日付欄は、表示の書式が利用環境で変わっても、valueはyyyy-mm-ddの形です。カレンダー上の一日と、世界のどこでも同じ瞬間を表す日時を分けると、変換する必要があるかを判断できます。
日付だけをそのまま受け渡す
次の例は26年内の申請期限を選び、JSONとして画面へ出すものです。実際の申請や保存は行いません。許可する年は練習用の条件です。
<label for="due-date">申請期限</label>
<input id="due-date" type="date" required
min="2026-01-01" max="2026-12-31">
<button id="preview-date" type="button">日付を確認する</button>
<pre id="date-result" role="status"></pre>
<script>
const dueDate = document.getElementById('due-date');
const output = document.getElementById('date-result');
document.getElementById('preview-date').addEventListener('click', () => {
output.textContent = '';
if (!dueDate.reportValidity()) return;
const payload = {dueDate: dueDate.value};
output.textContent = JSON.stringify(payload) + '\n保存はしていません。';
});
</script>
26年11月1日を選んだ場合の値は{"dueDate":"2026-11-01"}です。表示言語に合わせた年月日の並び方が変わっても、この文字列を送る設計にすれば、時差を付けた日時へ変換せずに日付を渡せます。受け取る側にも、これは日付だけの項目だと決めておきます。
UTCへ変わる場面を確かめる
JavaScriptでは標準の日付だけの文字列をDate.parseで読むとUTCとして解釈します。2026-11-01を日付のラベルとして保存したかったのに、UTCの午前0時という瞬間へ変えてしまうと、表示先の時差によって前日などに見えることがあります。
試しにnew Date('2026-11-01').toISOString()を見ると、UTCの2026-11-01T00:00:00.000Zになります。これは日付欄が勝手に前日へ変えたという意味ではありません。日付を日時へ変換し、その日時を別の場所の時刻で表示する処理が入ったことを確認します。
この問題はGASから画面へDate型を返せるかという通信形式の問題とも別です。入力した日付を保ちたいのか、申請を受け付けた瞬間を記録したいのかを先に分け、項目ごとに値の意味を決めます。
minとmaxは業務条件に合わせる
minとmaxは入力可能な範囲を指定します。画面に年度の条件を書いていても、指定が別の年になっていれば利用者が先へ進めません。表示説明、入力欄、保存先の検査で同じ範囲を使います。
空欄、範囲外、月末、うるう年の値も確認します。ブラウザの入力補助があるからといって、サーバー側で不正な日付を検査しなくてよいわけではありません。文字列を日付として受け取る契約と、実際に存在する日を確かめる検査をそろえてください。
この例はローカルのブラウザで日付の文字列と入力条件を確認するものです。実際のシート保存や、複数の利用者の環境を一括で検証した結果ではありません。日時が必要な項目では、この例へ単に時刻を足す前に、タイムゾーンと締切時刻をどこで決めるかを整理します。
