存在しない日付「2026-02-30」を、10言語のいちばん普通の日付の読み方に渡しました。8言語は「日付が正しくありません」と言い、PHP と JavaScript の2言語だけが、何も言わずに 2026年3月2日 として計算を続けました。
何をしたか
CODE Polyglot の入門 第8回 は、日付と日数を受け取って「その日の曜日」「◯日後の日付」「その月の最終日」を出すプログラムです。正解表は先に決めてあり、存在しない日付のときは「日付が正しくありません」と出すのが正解です。
各言語で、初心者が最初に習う読み方をそのまま使った版(つまずきやすい書き方)を用意し、毎朝の検証と同じ Linux の環境で動かしました。
| 言語 | 使った読み方 | 2026-02-30 を渡すと |
|---|---|---|
| Python | datetime.strptime | エラー → 「日付が正しくありません」 |
| Go | time.Parse | エラー → 同上 |
| Ruby | Date.parse | エラー → 同上 |
| Java・Kotlin | LocalDate.parse | エラー → 同上 |
| C# | DateTime.Parse | エラー → 同上 |
| Swift | DateFormatter | nil → 同上 |
| Rust | (標準に日付が無いので、年月日の整数で計算) | 同上 |
| PHP | new DateTime | エラーにならず、2026-03-02 として続ける |
| JavaScript | new Date | エラーにならず、2026-03-02 として続ける |
PHP が実際に出した答えはこうです。
2026-03-02 は月曜日です
1日後は 2026-03-03(火曜日)
この月の最終日は 2026-03-31
2月30日を「2月の30日目」=「2月28日の2日後」と読んで、3月2日に繰り越しています。止まらないので、エラーの処理(try / catch)を書いていても素通りします。
どう直したか
読み取る前に「その日が存在するか」を確かめます。PHP には checkdate があります。
$parts = explode("-", $argv[1]);
if (count($parts) !== 3 || !checkdate((int)$parts[1], (int)$parts[2], (int)$parts[0])) {
echo "日付が正しくありません\n";
exit;
}
JavaScript には checkdate に当たるものが無いので、作った日付の年・月・日が入力どおりかを比べます。
const d = new Date(Date.UTC(y, m - 1, day));
if (d.getUTCFullYear() !== y || d.getUTCMonth() !== m - 1 || d.getUTCDate() !== day) {
console.log("日付が正しくありません");
process.exit();
}
まとめ
- 「読めなかったらエラーになるはず」は、言語と関数によっては成り立たない
- 問い合わせフォームの生年月日や予約日など、人が入力した日付は、読んだあとに「入力どおりか」を確かめる
- 10言語の全プログラムと、つまずきの表は 入門 第8回 にあります。毎朝、実際に動かして確かめています
連載「その書き方、本当に通る?」(全4回)
- 第1回:「2026-02-30」を渡したら、PHP と JavaScript だけが黙って3月2日にした(この記事)
- 第2回:JavaScript で「月の最終日」を出したら、日本では毎回1日前になった
- 第3回:C# の Normalize(FormKC) が、Docker の中では何もしなかった
- 第4回:辞書の「取り出す順番」を10言語で20回ずつ試したら、5通りの性格に分かれた
Analyzegear


