JavaScript 日付処理
JavaScript は Date オブジェクトを使って日付と時刻を扱います。デジタル時計のようなものだと考えてください。現在時刻を表示し、任意の時刻を設定でき、2つの時刻の差を計算できます。
📖 まとめ
Date オブジェクトの作成
Date を作成する4つの一般的な方法:
HTML
<script>
console.log(new Date()); // 現在の日付と時刻
console.log(new Date("2025-06-19")); // 日付文字列
console.log(new Date(2025, 5, 19, 10, 30, 0)); // 年、月、日、時、分、秒
console.log(new Date(1718764800000)); // タイムスタンプ(ミリ秒)
</script>
大きな落とし穴:月はゼロ始まりです! 0 = 1月、11 = 12月です。new Date(2025, 5, 19) の 5 は6月を意味し、5月ではありません。これは Date オブジェクトで最も批判されている設計決定と言えるでしょう。
日付と時刻の取得
| メソッド | 返り値 | 備考 |
|---|---|---|
getFullYear() |
4桁の年 | getYear() は非推奨なので使わないこと |
getMonth() |
0~11 | 実際の月にするには +1 する |
getDate() |
1~31 | 月の日付 |
getDay() |
0~6 | 0 = 日曜日。月曜日ではありません! |
getHours() |
0~23 | — |
getMinutes() |
0~59 | — |
getSeconds() |
0~59 | — |
getDay() は曜日を返し、月の日付ではありません。月の日付を取得するには getDate() を使います。初心者がよく混同します。
日付と時刻の設定
対応する set メソッドがあります:setFullYear()、setMonth()、setDate()、setHours()、setMinutes()、setSeconds()。設定した値が範囲を超えると自動的に繰り上がります。
HTML
<script>
const d = new Date(2025, 5, 19);
d.setDate(32); // 自動的に7月2日になる
console.log(d.toLocaleDateString());
</script>
日付のフォーマット
| メソッド | 出力例 |
|---|---|
toLocaleDateString() |
"2025/6/19" |
toLocaleTimeString() |
"10:30:00" |
toLocaleString() |
"2025/6/19 10:30:00" |
これらのメソッドはブラウザのロケールに基づいて自動的にフォーマットされます。
タイムスタンプと時間差の計算
タイムスタンプとは、1970年1月1日 00:00:00 UTC から経過したミリ秒の数です。
HTML
<script>
console.log(Date.now()); // 現在のタイムスタンプを取得
console.log(new Date().getTime()); // 上記と同じ
</script>
時間差を計算する基本アプローチ:2つのタイムスタンプを引いてミリ秒の差を求め、その後変換します。
HTML
<script>
const start = Date.now();
for (let i = 0; i < 1000000; i++) {} // 何らかの処理をシミュレート
const end = Date.now();
const diff = end - start; // ミリ秒
const diffSeconds = diff / 1000; // 秒
console.log("経過時間: " + diff + "ms(" + diffSeconds + "秒)");
</script>
例:現在の日付と時刻の表示
HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>現在の日付と時刻</title>
<style>
body { font-family: sans-serif; padding: 20px; text-align: center; }
.clock { display: inline-block; padding: 24px 40px; background: #1a1a2e; color: #e0e0e0; border-radius: 12px; }
.time { font-size: 48px; font-weight: bold; color: #00d4ff; font-family: monospace; }
.date { font-size: 20px; margin-top: 8px; color: #a0a0c0; }
</style>
</head>
<body>
<h2>リアルタイム時計</h2>
<div class="clock">
<div class="time" id="time">--:--:--</div>
<div class="date" id="date">----/--/--</div>
</div>
<script>
function updateClock() {
const now = new Date();
const h = String(now.getHours()).padStart(2, "0");
const m = String(now.getMinutes()).padStart(2, "0");
const s = String(now.getSeconds()).padStart(2, "0");
document.getElementById("time").textContent = `${h}:${m}:${s}`;
const y = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, "0");
const d = String(now.getDate()).padStart(2, "0");
const weekdays = ["日", "月", "火", "水", "木", "金", "土"];
document.getElementById("date").textContent = `${y}/${month}/${d}(${weekdays[now.getDay()]})`;
}
updateClock();
setInterval(updateClock, 1000);
</script>
</body>
</html>
例:日付情報の詳細
HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>日付情報</title>
<style>
body { font-family: sans-serif; padding: 20px; }
table { border-collapse: collapse; margin: 16px 0; }
td, th { border: 1px solid #ddd; padding: 10px 16px; text-align: left; }
th { background: #4a90d9; color: #fff; }
.note { background: #fff8e1; padding: 12px; border-radius: 6px; border-left: 4px solid #f0ad4e; margin: 16px 0; }
</style>
</head>
<body>
<h2>Date オブジェクトのメソッド戻り値</h2>
<div id="output"></div>
<script>
const now = new Date();
const data = [
["getFullYear()", now.getFullYear(), "4桁の年"],
["getMonth()", now.getMonth(), "0〜11(実際の月には +1)"],
["getDate()", now.getDate(), "1〜31(月の日付)"],
["getDay()", now.getDay(), "0〜6(0 = 日曜日)"],
["getHours()", now.getHours(), "0〜23"],
["getMinutes()", now.getMinutes(), "0〜59"],
["getSeconds()", now.getSeconds(), "0〜59"],
["getTime()", now.getTime(), "タイムスタンプ(ミリ秒)"],
];
document.getElementById("output").innerHTML = `
<table>
<tr><th>メソッド</th><th>戻り値</th><th>説明</th></tr>
${data.map(r => `<tr><td><code>${r[0]}</code></td><td>${r[1]}</td><td>${r[2]}</td></tr>`).join("")}
</table>
<div class="note">
<strong>月はゼロ始まり</strong>:getMonth() は ${now.getMonth()} を返しますが、実際の月は ${now.getMonth()+1} です。
<strong>getDay() は曜日</strong>:${now.getDay()}(${["日","月","火","水","木","金","土"][now.getDay()]})を返します。日付ではありません!
</div>
`;
</script>
</body>
</html>
例:カウントダウンタイマー
HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>カウントダウン</title>
<style>
body { font-family: sans-serif; padding: 20px; text-align: center; }
.countdown { display: inline-block; padding: 24px; background: linear-gradient(135deg, #667eea, #764ba2); color: #fff; border-radius: 12px; margin: 16px 0; }
.countdown h3 { margin: 0 0 12px; font-size: 18px; }
.timer { display: flex; gap: 16px; justify-content: center; }
.unit { text-align: center; }
.number { font-size: 40px; font-weight: bold; font-family: monospace; }
.label { font-size: 12px; opacity: 0.8; }
.input-row { margin: 16px 0; }
input { padding: 8px 12px; font-size: 16px; border: 2px solid #ccc; border-radius: 6px; }
button { padding: 8px 20px; font-size: 16px; border: none; border-radius: 6px; cursor: pointer; background: #4a90d9; color: #fff; }
button:hover { background: #357abd; }
</style>
</head>
<body>
<h2>目標日時へのカウントダウン</h2>
<div class="input-row">
<input type="datetime-local" id="target" />
<button id="startBtn">カウントダウン開始</button>
</div>
<div class="countdown" id="countdown" style="display:none;">
<h3 id="targetLabel">残り時間</h3>
<div class="timer">
<div class="unit"><div class="number" id="days">0</div><div class="label">日</div></div>
<div class="unit"><div class="number" id="hours">0</div><div class="label">時間</div></div>
<div class="unit"><div class="number" id="minutes">0</div><div class="label">分</div></div>
<div class="unit"><div class="number" id="seconds">0</div><div class="label">秒</div></div>
</div>
</div>
<script>
const defaultTarget = new Date();
defaultTarget.setDate(defaultTarget.getDate() + 7);
const dateStr = defaultTarget.toISOString().slice(0, 16);
document.getElementById("target").value = dateStr;
let timer = null;
document.getElementById("startBtn").addEventListener("click", function() {
const target = new Date(document.getElementById("target").value);
if (isNaN(target.getTime())) {
alert("有効な日付と時刻を選択してください");
return;
}
document.getElementById("countdown").style.display = "inline-block";
document.getElementById("targetLabel").textContent =
`${target.toLocaleString()} までの残り時間`;
if (timer) clearInterval(timer);
function update() {
const now = Date.now();
const diff = target.getTime() - now;
if (diff <= 0) {
document.getElementById("days").textContent = "0";
document.getElementById("hours").textContent = "0";
document.getElementById("minutes").textContent = "0";
document.getElementById("seconds").textContent = "0";
document.getElementById("targetLabel").textContent = "時間切れです!";
clearInterval(timer);
return;
}
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((diff % (1000 * 60)) / 1000);
document.getElementById("days").textContent = days;
document.getElementById("hours").textContent = String(hours).padStart(2, "0");
document.getElementById("minutes").textContent = String(minutes).padStart(2, "0");
document.getElementById("seconds").textContent = String(seconds).padStart(2, "0");
}
update();
timer = setInterval(update, 1000);
});
</script>
</body>
</html>
例:日付差分計算機
HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>日付差分</title>
<style>
body { font-family: sans-serif; padding: 20px; }
.calc { max-width: 500px; margin: 16px auto; }
.row { margin: 12px 0; }
label { display: inline-block; width: 100px; font-weight: bold; }
input { padding: 8px 12px; font-size: 16px; border: 2px solid #ccc; border-radius: 6px; }
button { padding: 8px 20px; font-size: 16px; border: none; border-radius: 6px; cursor: pointer; background: #5cb85c; color: #fff; margin-top: 8px; }
button:hover { background: #449d44; }
.result { margin-top: 16px; padding: 16px; background: #f0f7ff; border-radius: 8px; border: 2px solid #4a90d9; }
.result div { margin: 4px 0; }
</style>
</head>
<body>
<h2 style="text-align:center;">日付差分計算機</h2>
<div class="calc">
<div class="row">
<label>開始日:</label>
<input type="date" id="start" />
</div>
<div class="row">
<label>終了日:</label>
<input type="date" id="end" />
</div>
<div style="text-align:center;">
<button id="calcBtn">計算する</button>
</div>
<div class="result" id="result" style="display:none;"></div>
</div>
<script>
const today = new Date();
const lastMonth = new Date();
lastMonth.setMonth(lastMonth.getMonth() - 1);
document.getElementById("start").value = lastMonth.toISOString().slice(0, 10);
document.getElementById("end").value = today.toISOString().slice(0, 10);
document.getElementById("calcBtn").addEventListener("click", function() {
const start = new Date(document.getElementById("start").value);
const end = new Date(document.getElementById("end").value);
if (isNaN(start.getTime()) || isNaN(end.getTime())) {
alert("有効な日付を選択してください");
return;
}
const diffMs = Math.abs(end - start);
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
const diffMinutes = Math.floor(diffMs / (1000 * 60));
const diffWeeks = Math.floor(diffDays / 7);
document.getElementById("result").style.display = "block";
document.getElementById("result").innerHTML = `
<div><strong>日数:</strong> ${diffDays}</div>
<div><strong>時間:</strong> ${diffHours}</div>
<div><strong>分:</strong> ${diffMinutes}</div>
<div><strong>約:</strong> ${diffWeeks} 週間と ${diffDays % 7} 日</div>
`;
});
</script>
</body>
</html>
❓ よくある質問
Q
getMonth() に +1 が必要なのはなぜですか?A Java の
Date クラスがこのように設計されており、JavaScript がその「伝統」を継承しました。誰もがばかげた設計だと同意しますが、変更できません。既存のコードがこの動作に依存しすぎています。覚えましょう。Q
new Date("2025-06-19") と new Date(2025, 5, 19) には違いがありますか?A あります。文字列で解析された日付はデフォルトで UTC の午前0時になりますが、パラメータ形式はローカル時刻を使用します。表示される時刻は8時間(UTC+8 の場合)異なることがあります。時刻ではなく日付だけが必要な場合は、パラメータ形式の方が安全です。
Q 年齢はどうやって計算しますか?
A 現在の年から誕生年を引き、今年の誕生日が過ぎているかどうかを確認します。現在の月が誕生月より少ない場合、または月が同じで現在の日が誕生日より少ない場合は、年齢から1を引きます。
📝 演習
formatDate(date)関数を書きましょう。"YYYY-MM-DD(曜日)"の形式で文字列を返してください。月と日がゼロパディングされていることを確認してください。getAge(birthday)関数を書きましょう。日付文字列(例:"2000-03-15")を引数に取り、現在の年齢を満年数で返してください。- 「何分前」機能を構築しましょう:過去の日付が与えられた場合、「X年Xか月X日前」または「X日前」または「X時間前」を表示し、時間差に基づいて適切なフォーマットを自動選択してください。



