雖然每個月的日子都差不多是固定的,但是如果能使用 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()` 的速度很慢,所以用那一個方法來取得每月最後一,可以因應情況自行決定。