This is IT

技術、日常

【JavaScript】ある月の最終日の日付を取得する方法

地味に混乱したためメモ書き。

getMonth()メソッド

まずは単純に現時点での日付・時刻を取得する方法。

var now = new Date();

console.log(now)

// 2023-07-14T11:41:20.194Z

これは特に問題がない。 JavaScriptでは、getMonth()メソッドでDateオブジェクトから「月」を取得できる。

var now = new Date();

console.log(now.getMonth())

// 6

現時点は「7月」のはずなのに、6が出力されてしまう。 これはgetMonth()は0を起点として月を返すため。

var now = new Date();

console.log(now.getMonth() + 1)

// 7

こうすることで欲しかった「7」を取得できる。

最終日の日付を取得

本題。 Date.new()では引数に何も渡さないと、インスタンス化された時点の日付、時刻を返す。

var now = new Date();

console.log(now)

// 2023-07-14T11:41:20.194Z

では、引数を渡すとどうなるのだろうか? new Date(year, monthIndex, day, hours, minutes, seconds, milliseconds)の順番で引数を渡せる。

var sample = new Date(1995, 11, 17, 18, 24, 0)

console.log(sample)

// 1995-12-16T18:24:00.000Z

繰り返しになるがDateオブジェクト初めの月の基準を0としているので、引数に11を渡したが、「12月」として返ってくる。

ここからが鍵となるが、Dateオブジェクトでは西暦や月、日付にありえない値を渡すとオーバーフロー、またはアンダーフローを起こす。

以下はMDN Web Docsの文章。

When a segment overflows or underflows its expected range, it usually "carries over to" or "borrows from" the higher segment. For example, if the month is set to 12 (months are zero-based, so December is 11), it become the January of the next year. If the day of month is set to 0, it becomes the last day of the previous month. This also applies to dates specified with the date time string format.

この中の例として挙げられている、

If the day of month is set to 0, it becomes the last day of the previous month.

には、日付に「0」を指定するとアンダーフローを起こし、前月の最終日を取得すると書いてある。 これを利用して、ある月の最終日を取得する。

例えば、2023年2月の最終日を取得するとしたら、

var sample = new Date(2023, 2, 0)

console.log(sample.getDate())

// 28

ナイス。

参考

Date.prototype.getMonth() Date() コンストラクター MDN Web Docs