JavaScript日付の加算・減算 - 初心者向け日付操作ガイド
JavaScript日付オブジェクトの加算・減算方法を初心者向けに解説。日・月・年の計算、期間計算、日付比較など実用的な操作方法を分かりやすく紹介します。
JavaScript日付の加算・減算 - 初心者向け日付操作ガイド
みなさん、JavaScriptで日付の計算をしたいと思ったことはありませんか?
「今日から30日後の日付を知りたい」 「2つの日付の差を計算したい」
こんな場面に遭遇したことはありませんか?
この記事では、JavaScript日付の加算・減算を初心者向けに分かりやすく解説します。 基本的な操作から実際に使える応用例まで、完全なコード付きでお教えします。
一緒に日付操作をマスターしていきましょう!
Dateオブジェクトって何?
簡単に言うと日付を扱う道具
JavaScriptで日付を操作するには、Dateオブジェクトを使います。 これは「日付と時刻を表現するための専用の道具」です。
// 現在の日時を取得const now = new Date();console.log(now); // 現在の日時が表示される
// 特定の日付を作成const specificDate = new Date('2025-07-06');console.log(specificDate); // 2025年7月6日
new Date()
で新しい日付オブジェクトを作成できます。
何も指定しなければ現在の日時、文字列を渡せば特定の日付を作れます。
年・月・日を数字で指定することもできます。
// 年、月、日を指定して作成(月は0から始まることに注意)const dateFromNumbers = new Date(2025, 6, 6); // 2025年7月6日console.log(dateFromNumbers);
// 時刻も含めて作成const dateWithTime = new Date(2025, 6, 6, 14, 30, 0); // 2025年7月6日 14:30:00console.log(dateWithTime);
重要なポイント:月は0から始まるので、7月は「6」と指定します。
Dateオブジェクトの仕組みを理解しよう
日付操作で失敗しないために、重要なポイントを確認しましょう。
// 注意点1: 月は0から始まるconst january = new Date(2025, 0, 1); // 1月const december = new Date(2025, 11, 31); // 12月
console.log(january.getMonth()); // 0(1月)console.log(december.getMonth()); // 11(12月)
// 注意点2: 日付は内部的にミリ秒で管理されるconst timestamp = now.getTime();console.log(timestamp); // 1970年1月1日からのミリ秒
日付は内部でミリ秒として管理されています。 この仕組みを理解すると、日付計算がやりやすくなります。
日付の加算・減算をやってみよう
日を足したり引いたりする方法
まずは基本的な日の加算・減算から始めましょう。
// 現在の日付を基準にした加算・減算const today = new Date();console.log("今日:", today.toLocaleDateString());
// 1日後const tomorrow = new Date(today);tomorrow.setDate(today.getDate() + 1);console.log("明日:", tomorrow.toLocaleDateString());
// 1週間後const nextWeek = new Date(today);nextWeek.setDate(today.getDate() + 7);console.log("1週間後:", nextWeek.toLocaleDateString());
setDate()
メソッドで日付を設定し、getDate()
で現在の日を取得します。
元の日付に数値を足したり引いたりするだけです。
過去の日付も同じように計算できます。
// 10日前const tenDaysAgo = new Date(today);tenDaysAgo.setDate(today.getDate() - 10);console.log("10日前:", tenDaysAgo.toLocaleDateString());
// 30日後const thirtyDaysLater = new Date(today);thirtyDaysLater.setDate(today.getDate() + 30);console.log("30日後:", thirtyDaysLater.toLocaleDateString());
マイナスの値を使えば、過去の日付を計算できます。
便利な関数を作ってみよう
毎回同じコードを書くのは大変なので、関数にまとめましょう。
// 日数を加算する関数function addDays(date, days) { const result = new Date(date); result.setDate(result.getDate() + days); return result;}
// 使用例const baseDate = new Date('2025-07-06');console.log("基準日:", baseDate.toLocaleDateString());console.log("5日後:", addDays(baseDate, 5).toLocaleDateString());console.log("3日前:", addDays(baseDate, -3).toLocaleDateString());
このaddDays
関数を使えば、簡単に日付計算ができます。
元の日付オブジェクトは変更せず、新しい日付オブジェクトを返します。
実用的な例も作ってみましょう。
// より実用的な例function calculateDeliveryDate(orderDate, deliveryDays) { const delivery = addDays(orderDate, deliveryDays); return { orderDate: orderDate.toLocaleDateString(), deliveryDate: delivery.toLocaleDateString(), deliveryDays: deliveryDays };}
const order = new Date('2025-07-06');const deliveryInfo = calculateDeliveryDate(order, 3);console.log("注文日:", deliveryInfo.orderDate);console.log("配送日:", deliveryInfo.deliveryDate);console.log("配送日数:", deliveryInfo.deliveryDays + "日");
注文日から配送日を計算する関数です。 実際の業務でも役立ちそうですね。
月の加算・減算にチャレンジ
基本的な月の操作
月の計算は、日付よりも少し複雑です。 月末の日数が異なるためです。
// 月を加算・減算する関数function addMonths(date, months) { const result = new Date(date); result.setMonth(result.getMonth() + months); return result;}
// 使用例const startDate = new Date('2025-07-15');console.log("開始日:", startDate.toLocaleDateString());
// 1ヶ月後const oneMonthLater = addMonths(startDate, 1);console.log("1ヶ月後:", oneMonthLater.toLocaleDateString());
// 3ヶ月前const threeMonthsAgo = addMonths(startDate, -3);console.log("3ヶ月前:", threeMonthsAgo.toLocaleDateString());
setMonth()
メソッドで月を設定し、getMonth()
で現在の月を取得します。
特殊なケースも確認してみましょう。
// 月末の特殊なケースconst endOfMonth = new Date('2025-01-31');console.log("1月31日:", endOfMonth.toLocaleDateString());
const nextMonth = addMonths(endOfMonth, 1);console.log("1ヶ月後:", nextMonth.toLocaleDateString()); // 2月28日または29日になる
1月31日の1ヶ月後は、2月には31日がないので2月28日(または29日)になります。
月末を考慮した安全な計算
月末の問題を解決する関数を作ってみましょう。
// 月末を考慮した月加算関数function addMonthsSafely(date, months) { const result = new Date(date); const originalDay = result.getDate(); // 月を変更 result.setMonth(result.getMonth() + months); // 日付が変わった場合(月末を超えた場合)の処理 if (result.getDate() !== originalDay) { // 前月の最終日に設定 result.setDate(0); } return result;}
この関数では、元の日付と計算後の日付を比較しています。 日付が変わった場合は、その月の最終日に設定し直します。
実際に使ってみましょう。
// 使用例const januaryEnd = new Date('2025-01-31');console.log("1月31日:", januaryEnd.toLocaleDateString());
const februaryResult = addMonthsSafely(januaryEnd, 1);console.log("安全な1ヶ月後:", februaryResult.toLocaleDateString()); // 2月28日
これで、月末でも安全に計算できます。
支払いスケジュールの計算にも使えます。
// 実用的な支払日計算の例function calculateNextPaymentDate(currentDate, intervalMonths) { return addMonthsSafely(currentDate, intervalMonths);}
const firstPayment = new Date('2025-01-31');const payments = [];
for (let i = 0; i < 6; i++) { const paymentDate = calculateNextPaymentDate(firstPayment, i); payments.push({ 回数: i + 1, 支払日: paymentDate.toLocaleDateString() });}
console.log("支払スケジュール:", payments);
毎月の支払日を自動で計算できます。
年の加算・減算も覚えよう
基本的な年の操作
年の操作は比較的シンプルです。 ただし、うるう年に注意が必要です。
// 年を加算・減算する関数function addYears(date, years) { const result = new Date(date); result.setFullYear(result.getFullYear() + years); return result;}
// 使用例const birthDate = new Date('1990-03-15');console.log("生年月日:", birthDate.toLocaleDateString());
// 年齢計算const currentDate = new Date();const age = currentDate.getFullYear() - birthDate.getFullYear();console.log("現在の年齢(概算):", age + "歳");
setFullYear()
メソッドで年を設定し、getFullYear()
で年を取得します。
より正確な年齢計算も作ってみましょう。
// より正確な年齢計算function calculateAge(birthDate, referenceDate = new Date()) { let age = referenceDate.getFullYear() - birthDate.getFullYear(); // 誕生日がまだ来ていない場合は1歳減らす const birthMonth = birthDate.getMonth(); const birthDay = birthDate.getDate(); const currentMonth = referenceDate.getMonth(); const currentDay = referenceDate.getDate(); if (currentMonth < birthMonth || (currentMonth === birthMonth && currentDay < birthDay)) { age--; } return age;}
const exactAge = calculateAge(birthDate);console.log("正確な年齢:", exactAge + "歳");
誕生日が来ているかどうかを判定して、正確な年齢を計算しています。
うるう年を考慮した処理
うるう年の特殊なケースも処理しましょう。
// うるう年判定関数function isLeapYear(year) { return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);}
// うるう年を考慮した年加算function addYearsWithLeapYear(date, years) { const result = new Date(date); const originalMonth = result.getMonth(); const originalDay = result.getDate(); result.setFullYear(result.getFullYear() + years); // 2月29日の特殊処理 if (originalMonth === 1 && originalDay === 29) { const newYear = result.getFullYear(); if (!isLeapYear(newYear)) { result.setDate(28); // うるう年でない場合は2月28日に } } return result;}
2月29日の1年後がうるう年でない場合、2月28日に調整します。
実際に試してみましょう。
// 使用例const leapDayDate = new Date('2024-02-29'); // うるう日console.log("うるう日:", leapDayDate.toLocaleDateString());
const nextYear = addYearsWithLeapYear(leapDayDate, 1);console.log("1年後:", nextYear.toLocaleDateString()); // 2025年2月28日
console.log("2024年はうるう年:", isLeapYear(2024));console.log("2025年はうるう年:", isLeapYear(2025));
うるう年の判定も含めて、正確に計算できます。
時間の加算・減算もやってみよう
時・分・秒の操作
日付だけでなく、時間の操作も覚えましょう。
// 時間を加算・減算する関数群function addHours(date, hours) { const result = new Date(date); result.setHours(result.getHours() + hours); return result;}
function addMinutes(date, minutes) { const result = new Date(date); result.setMinutes(result.getMinutes() + minutes); return result;}
function addSeconds(date, seconds) { const result = new Date(date); result.setSeconds(result.getSeconds() + seconds); return result;}
それぞれ、時・分・秒を操作する関数です。 日付の操作と同じ考え方で作れます。
実際に使ってみましょう。
// 使用例const startTime = new Date('2025-07-06T10:30:00');console.log("開始時刻:", startTime.toLocaleString());
const twoHoursLater = addHours(startTime, 2);console.log("2時間後:", twoHoursLater.toLocaleString());
const thirtyMinutesLater = addMinutes(startTime, 30);console.log("30分後:", thirtyMinutesLater.toLocaleString());
const fortyFiveSecondsLater = addSeconds(startTime, 45);console.log("45秒後:", fortyFiveSecondsLater.toLocaleString());
時間の加算も簡単にできます。
会議の終了時刻を計算する実用的な例も作ってみましょう。
// 実用的な例:会議の終了時刻計算function calculateMeetingEndTime(startTime, durationMinutes) { const endTime = addMinutes(startTime, durationMinutes); return { 開始時刻: startTime.toLocaleString(), 終了時刻: endTime.toLocaleString(), 所要時間: durationMinutes + "分" };}
const meetingStart = new Date('2025-07-06T14:00:00');const meetingInfo = calculateMeetingEndTime(meetingStart, 90);console.log("会議情報:", meetingInfo);
会議の開始時刻と所要時間から、終了時刻を自動計算できます。
日付の差を計算してみよう
2つの日付の差を求める方法
日付の差分を計算すると、期間や経過時間が分かります。
// 日付の差分を計算する関数function dateDifference(date1, date2) { const diffInMs = Math.abs(date2.getTime() - date1.getTime()); const msPerDay = 1000 * 60 * 60 * 24; const msPerHour = 1000 * 60 * 60; const msPerMinute = 1000 * 60; const days = Math.floor(diffInMs / msPerDay); const hours = Math.floor((diffInMs % msPerDay) / msPerHour); const minutes = Math.floor((diffInMs % msPerHour) / msPerMinute); const seconds = Math.floor((diffInMs % msPerMinute) / 1000); return { totalMs: diffInMs, days: days, hours: hours, minutes: minutes, seconds: seconds, formatted: `${days}日 ${hours}時間 ${minutes}分 ${seconds}秒` };}
この関数では、2つの日付の差をミリ秒で計算してから、日・時・分・秒に変換しています。
使ってみましょう。
// 使用例const startDate = new Date('2025-07-01T09:00:00');const endDate = new Date('2025-07-06T15:30:45');
const difference = dateDifference(startDate, endDate);console.log("日付の差:", difference.formatted);console.log("総日数:", difference.days + "日");
2つの日付の正確な差が分かります。
プロジェクトの期間計算にも応用できます。
// プロジェクトの期間計算function calculateProjectDuration(startDate, endDate) { const diff = dateDifference(startDate, endDate); const workingDays = Math.floor(diff.days * (5/7)); // 平日のみ概算 return { 総日数: diff.days, 営業日数概算: workingDays, 詳細: diff.formatted };}
const projectStart = new Date('2025-07-01');const projectEnd = new Date('2025-08-15');const projectDuration = calculateProjectDuration(projectStart, projectEnd);console.log("プロジェクト期間:", projectDuration);
営業日の概算も含めて、プロジェクト期間を計算できます。
年齢や勤続年数の詳細計算
より詳細な期間計算も作ってみましょう。
// より詳細な期間計算function calculateDetailedAge(birthDate, referenceDate = new Date()) { let years = referenceDate.getFullYear() - birthDate.getFullYear(); let months = referenceDate.getMonth() - birthDate.getMonth(); let days = referenceDate.getDate() - birthDate.getDate(); // 日の調整 if (days < 0) { months--; const prevMonth = new Date(referenceDate.getFullYear(), referenceDate.getMonth(), 0); days += prevMonth.getDate(); } // 月の調整 if (months < 0) { years--; months += 12; } return { years: years, months: months, days: days, formatted: `${years}歳 ${months}ヶ月 ${days}日` };}
年・月・日まで詳細に計算する関数です。
実際に使ってみましょう。
// 使用例const birthDate = new Date('1990-03-15');const detailedAge = calculateDetailedAge(birthDate);console.log("詳細な年齢:", detailedAge.formatted);
// 勤続年数の計算function calculateServicePeriod(hireDate) { const today = new Date(); const service = calculateDetailedAge(hireDate, today); return { 入社日: hireDate.toLocaleDateString(), 勤続期間: service.formatted, 勤続年数: service.years };}
const hireDate = new Date('2020-04-01');const serviceInfo = calculateServicePeriod(hireDate);console.log("勤続情報:", serviceInfo);
入社日から勤続年数を正確に計算できます。
実用的なテクニック
営業日の計算
土日を除いた営業日の計算方法です。
// 営業日計算(土日を除く)function addBusinessDays(date, days) { const result = new Date(date); let addedDays = 0; while (addedDays < days) { result.setDate(result.getDate() + 1); // 土曜日(6)と日曜日(0)を除く if (result.getDay() !== 0 && result.getDay() !== 6) { addedDays++; } } return result;}
土日をスキップして、営業日だけを数える関数です。
使ってみましょう。
// 使用例const orderDate = new Date('2025-07-04'); // 金曜日console.log("注文日:", orderDate.toLocaleDateString(), "(" + ['日', '月', '火', '水', '木', '金', '土'][orderDate.getDay()] + ")");
const deliveryDate = addBusinessDays(orderDate, 3);console.log("配送日(3営業日後):", deliveryDate.toLocaleDateString(), "(" + ['日', '月', '火', '水', '木', '金', '土'][deliveryDate.getDay()] + ")");
金曜日から3営業日後は、翌週の水曜日になります。
営業日数を数える関数も作れます。
// 営業日数の計算function countBusinessDays(startDate, endDate) { const start = new Date(startDate); const end = new Date(endDate); let count = 0; while (start <= end) { if (start.getDay() !== 0 && start.getDay() !== 6) { count++; } start.setDate(start.getDate() + 1); } return count;}
const businessDays = countBusinessDays(new Date('2025-07-01'), new Date('2025-07-31'));console.log("7月の営業日数:", businessDays + "日");
指定した期間の営業日数を計算できます。
月の最初と最後の日
月の境界日を取得する便利な関数です。
// 月の最初の日を取得function getFirstDayOfMonth(date) { return new Date(date.getFullYear(), date.getMonth(), 1);}
// 月の最後の日を取得function getLastDayOfMonth(date) { return new Date(date.getFullYear(), date.getMonth() + 1, 0);}
// 月の日数を取得function getDaysInMonth(date) { return getLastDayOfMonth(date).getDate();}
月の境界を簡単に取得できます。
使ってみましょう。
// 使用例const someDate = new Date('2025-07-15');console.log("基準日:", someDate.toLocaleDateString());console.log("月初:", getFirstDayOfMonth(someDate).toLocaleDateString());console.log("月末:", getLastDayOfMonth(someDate).toLocaleDateString());console.log("月の日数:", getDaysInMonth(someDate) + "日");
月間レポートの期間計算にも使えます。
// 月間レポートの期間計算function getMonthlyReportPeriod(year, month) { const firstDay = new Date(year, month - 1, 1); // 月は0から始まるので-1 const lastDay = getLastDayOfMonth(firstDay); return { 年月: `${year}年${month}月`, 開始日: firstDay.toLocaleDateString(), 終了日: lastDay.toLocaleDateString(), 日数: getDaysInMonth(firstDay) };}
const reportPeriod = getMonthlyReportPeriod(2025, 7);console.log("月間レポート期間:", reportPeriod);
月間レポートの期間を自動計算できます。
安全な日付操作のために
エラーを防ぐ安全な関数
日付操作でエラーが起きないように、安全な関数を作りましょう。
// 日付の妥当性チェックfunction isValidDate(date) { return date instanceof Date && !isNaN(date.getTime());}
// 安全な日付加算関数function safeDateAdd(date, unit, amount) { if (!isValidDate(date)) { throw new Error('無効な日付が指定されました'); } if (typeof amount !== 'number' || isNaN(amount)) { throw new Error('無効な数値が指定されました'); } const result = new Date(date); try { switch (unit.toLowerCase()) { case 'day': case 'days': result.setDate(result.getDate() + amount); break; case 'month': case 'months': result.setMonth(result.getMonth() + amount); break; case 'year': case 'years': result.setFullYear(result.getFullYear() + amount); break; default: throw new Error(`サポートされていない単位です: ${unit}`); } if (!isValidDate(result)) { throw new Error('計算結果が無効な日付になりました'); } return result; } catch (error) { console.error('日付計算エラー:', error.message); return null; }}
入力値をチェックして、エラーが起きないように工夫しています。
使ってみましょう。
// 使用例const baseDate = new Date('2025-07-06');
try { const futureDate = safeDateAdd(baseDate, 'days', 30); console.log("30日後:", futureDate?.toLocaleDateString()); const pastDate = safeDateAdd(baseDate, 'months', -6); console.log("6ヶ月前:", pastDate?.toLocaleDateString()); // エラーケース const invalidResult = safeDateAdd(baseDate, 'invalid_unit', 5); console.log("無効な単位の結果:", invalidResult); // null } catch (error) { console.error("エラーが発生しました:", error.message);}
エラーが起きても、プログラムが止まることはありません。
まとめ
JavaScript日付の加算・減算について詳しく解説しました。
基本的な操作:
- 日の加算・減算:
setDate()
とgetDate()
を使用 - 月の加算・減算:
setMonth()
とgetMonth()
を使用(月末に注意) - 年の加算・減算:
setFullYear()
とgetFullYear()
を使用(うるう年に注意) - 時間の加算・減算:各時間単位に対応するメソッドを使用
実用的なテクニック:
- 営業日の計算(土日を除く)
- 月の境界日の取得
- 期間や年齢の詳細計算
- 安全なエラーハンドリング
重要なポイント:
- 月は0から始まる(1月=0、12月=11)
- 月末やうるう年の特殊ケースに注意
- 元の日付オブジェクトを変更せず、新しいオブジェクトを作成
- 入力値の妥当性チェックを忘れない
次のステップ:
- より複雑な日付計算に挑戦
- タイムゾーンを考慮した処理
- 日付ライブラリ(moment.js、date-fnsなど)の活用
JavaScriptの日付操作は、最初は複雑に感じるかもしれません。 しかし、基本的なパターンを覚えれば、様々な日付計算ができるようになります。
ぜひ今日から、これらのテクニックを使って実用的なアプリケーションを作ってみませんか?