コンテンツにスキップ

n か月後の日付

ここではオフィススクリプトを使って、1 か月後や n か月後の日付を求める方法を、サンプルコードと併せて解説します。

DateオブジェクトのgetMonthメソッドで現在の月を取得し、加算した値をsetMonthメソッドに渡します。

1か月後の日付を求めるサンプル
function main(workbook: ExcelScript.Workbook) {
const date = new Date(2024, 3, 15); // 2024 年 4 月 15 日
date.setMonth(date.getMonth() + 1);
console.log(date.toLocaleDateString()); // 2024/5/15
}

12 月に月を加算した場合も、自動的に翌年に繰り上げられます。日付が 28 日以前であれば、この方法で問題ありません。

月末の日付に加算すると翌々月にずれる

Section titled “月末の日付に加算すると翌々月にずれる”

元の日付が 29 日以降の場合、加算した先の月にその日が存在しないことがあります。

以下は 2024 年 1 月 31 日に 1 か月を加算した場合の例です。setMonth(1)で「2024 年 2 月 31 日」が指定されますが、2 月は 29 日までのため、超えた 2 日分が 3 月に繰り越されます。

日付や加える数を変えて、どのような場合にずれが起きるかを確かめてみましょう。

date.setMonth(date.getMonth() + 1)

  1. 元の日付2024131
  2. setMonth(1) で指定した日付2024231存在しない日付
  3. 実際の日付202432
  • 月は 0 から数えるため、0 は 1 月を表します。
  • 2024 年 2 月は 29 日までのため、超えた 2 日分が翌月に繰り越されます。

日付や加える数を変えて、繰り上げのしかたを確かめてみましょう。

月を減算する場合も同じです。3 月 31 日の 1 か月前は「2 月 31 日」となり、2 月ではなく 3 月 2 日になります。

date.setMonth(date.getMonth() - 1)

  1. 元の日付2024331
  2. setMonth(1) で指定した日付2024231存在しない日付
  3. 実際の日付202432
  • 月は 0 から数えるため、2 は 3 月を表します。
  • 2024 年 2 月は 29 日までのため、超えた 2 日分が翌月に繰り越されます。

日付や加える数を変えて、繰り上げのしかたを確かめてみましょう。

締め日や支払期日の計算でこのずれが起きると、1 か月以上先の日付として扱われてしまいます。

月末を超えないように加算する

Section titled “月末を超えないように加算する”

VBA のDateAdd関数と同じく、存在しない日付になる場合は月の末日に合わせる関数を作成します。

nか月後の日付を求める関数
function main(workbook: ExcelScript.Workbook) {
const date = new Date(2024, 0, 31); // 2024 年 1 月 31 日
console.log(addMonths(date, 1).toLocaleDateString()); // 2024/2/29
console.log(addMonths(date, 2).toLocaleDateString()); // 2024/3/31
console.log(addMonths(date, 3).toLocaleDateString()); // 2024/4/30
console.log(addMonths(date, -1).toLocaleDateString()); // 2023/12/31
}
/**
* n か月後の日付を返す(存在しない日付になる場合は、その月の末日にする)
* @param date 元の日付(変更されない)
* @param months 加算する月数(負数なら n か月前)
*/
function addMonths(date: Date, months: number): Date {
/** 加算した先の月の初日 */
const firstDay = new Date(date.getFullYear(), date.getMonth() + months, 1);
/** 加算した先の月の末日の「日」(翌月の 0 日) */
const lastDay = new Date(firstDay.getFullYear(), firstDay.getMonth() + 1, 0).getDate();
return new Date(firstDay.getFullYear(), firstDay.getMonth(), Math.min(date.getDate(), lastDay));
}

処理の流れは次のとおりです。

  1. 加算した先の月の 初日 を作成します。1 日はどの月にも存在するため、ここでずれは起きません。
  2. その月の末日を求めます(翌月の 0 日)。
  3. 元の日付の「日」と月末の「日」のうち、小さい方を日として設定します。

月末日の求め方は、以下の記事で詳しく解説しています。

年を加算するsetFullYearメソッドでも、同じずれが起きます。うるう日(2 月 29 日)に 1 年を加算すると、翌年に 2 月 29 日が存在しないため 3 月 1 日になります。

date.setFullYear(date.getFullYear() + 1)

  1. 元の日付2024229
  2. setFullYear(2025) で指定した日付2025229存在しない日付
  3. 実際の日付202531
  • 2025 年 2 月は 28 日までのため、超えた 1 日分が翌月に繰り越されます。

日付や加える数を変えて、繰り上げのしかたを確かめてみましょう。

月末に合わせたい場合は、先ほどのaddMonths関数に 12 か月を指定します。

const leapDay = new Date(2024, 1, 29); // 2024 年 2 月 29 日
console.log(addMonths(leapDay, 12).toLocaleDateString()); // 2025/2/28