雖然每個月的日子都差不多是固定的,但是如果能使用 Program 計算出日期相關的數值,就更為方便易用。 ### TL;DR 我們可以使用 Date Object 來快速計算出每個月份的最後一日。 ```js // year var year = 2020; // month var month = 0; // get date var date = new Date(year, month + 1, 0); ``` ### 潤年 Leap Year 在小學時都會有教過 : 一月大、二月小、三月大、四月小、五月大、六月小、七月大、八月大、九月小、十月大、十一月小、十二月大。 實質上上面的意思是 : 1 月有 31 日;2 月有 28 或 29 日;3 月有 31 日;4 月有 30 日;5 月有 31 日;6 月有 30 日;7 月有 31 日;8 月有 31 日;9 月有 30 日;10 月有 31 日;11 月有 30 日;12 月有 31 日。 潤年是指二月有 29 日的年份,而潤年是有一條公式可以計算的。 ### 潤年定義方法 年份是 4 的倍數及年份不是 100 的倍數但年份是 400 的倍數。 以上的規則可以使用以下的邏輯判別出來。 ```js /** * check year is leap year */ function isLeapYear(year) { return ((year % 4) === 0 && (year % 100) !== 0) || (year % 400) === 0; } ``` ### 找出每個月份的最後一日 由以上的資料,我們可以總結出下面的邏輯用來計算每個月份的最後一日。 ```js /** * get last date of month */ function getDaysOfMonth(year, month) { // get date by month switch (month) { case 2: return isLeapYear(year) ? 29 : 28; case 4: case 6: case 9: case 11: return 30; default: return 31; } } ``` 但是... 其實 Javascript 入面的 Date Object 已經可以快速計算出來。 ```js // year var year = 2020; // month var month = 0; // get date var date = new Date(year, month + 1, 0); ``` 上面的 `new Date()` 方法是把目前的月份加上 1,然後再把日子設定為 0,這樣 Date Object 便會設定為下一個月的 0 日,但因為 0 日是一個不合法的日期,所以 Date Object 會把 0 設定為 1 的前一日,也即是設定月份的最後一日。 不過有人回報過使用 `new Date()` 的速度很慢,所以用那一個方法來取得每月最後一,可以因應情況自行決定。