JavaScript日付の加算・減算 - 初心者向け日付操作ガイド

JavaScript日付オブジェクトの加算・減算方法を初心者向けに解説。日・月・年の計算、期間計算、日付比較など実用的な操作方法を分かりやすく紹介します。

Learning Next 運営
37 分で読めます

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:00
console.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の日付操作は、最初は複雑に感じるかもしれません。 しかし、基本的なパターンを覚えれば、様々な日付計算ができるようになります。

ぜひ今日から、これらのテクニックを使って実用的なアプリケーションを作ってみませんか?

関連記事