input[type=date] で年に6桁入力できてしまう

はじめに。

input[type=date] のテキストボックスに年が6桁入力できる様子。

Google Chrome だとこんな感じです。

ブラウザ標準のタグなので、動作は使用しているブラウザに依存してしまいます。

ブラウザのバグかなと思い、Chrome のコミュニティなどを調べてみたがどうもそんな報告もない様子…

なぜ年に6桁入力できる?

ブラウザでの表示自体は日付となっているが、データとしては数値のデータ型に変換できることはエンジニアであれば一度は聞いたことがあるかと思います。

日付のデータ型 は UTC (協定世界時) の 1970/01/01 0:00 からの経過ミリ秒を表すことは知られています。

数値型のデータ範囲は Java を例にすると以下のようなものがあります。

データ型サイズ値の範囲備考
byte1byte (8bit)-128〜1272^8
short2byte (16bit)-32768〜327672^16
int4byte (32bit)-2147483648〜21474836472^32
*約+21億
long16byte (64bit)-9223372036854775808〜92233720368547758072^64

各種ブラウザもこのあたりを使っているのかと思いましたが、調べてみるとどうもちがう様子です。

2024年2月現在、ECMA-262 という国際的な標準規格(JavaScript がメインのようです)で標準化が進められています。

引用)https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Date

日付の最大は、実は 275760年9月13日(1970/01/01 + 100,000,000日)だった…!

これでブラウザの動作不具合ではないことが判明しました…

*つまりは、標準動作だったのです。年に6桁できることは今後も続くでしょう…

年の入力を4桁に制限したい…!

日付(type=date)はmax属性をもっていますので、ここに「9999/12/31」を設定することで対応ができそうです。

日付のmax属性指定は、下記スクリプトを共通 JavaScript として作成することで一括で対応可能です。

// ■ input[type="date"] 年が6桁入力できてしまう
// 一括設定して入力を制限する(jQuery使用版)
$("input[type='date']").attr('max', '9999-12-31');

もしくは、jQuery を使用しないのであれば、

// ■ input[type="date"] 年が6桁入力できてしまう
// 一括設定して入力を制限する(DOM操作:Document Object Model)
let forEach = Array.prototype.forEach;
let type_date = document.querySelectorAll("input[type='date']");
forEach.call(type_date, function (elem) {
    elem.max = '9999-12-31';
});

max属性を指定した場合の、2023年2月現在の各ブラウザの動作状況です。

 Google Chrome (ver.121) は年入力4桁制限される
 Mozilla Firefox () は検索ボタンを押したときに無効な日付、
 Edge はChromiumベースなのでおそらく Chrome と同じ動きになると想定。

HTMLタグをセーフティと信用しないで、必ずサーバー側での入力チェック(バリデーション)は必要です…!

input[type=text] を使う場合は、日付の整合性、範囲チェックは必須になりそうですね。