我們在小學階段都會學到平年(common year)和閏年(leap year)的判斷方式,以及這兩種年份是差在前者的二月有28天,後者則是有29天。所以平年整年一共有365天;閏年整年一共有366年。這是身為一個地球人的基本常識,但在小學的時候,老師可能只會告訴我們把西元年份的數字除以4,如果可以整除,那麼這年就是閏年,否則是平年。老師說的也不能說是錯的,只是不太完整,實際上,閏年的正確判斷方式為「四年一閏;百年不閏,四百年再閏」。



為什麼會有閏年?

地球自轉一圈定義為一天,地球繞太陽公轉一圈定義為一年,所以地球自轉365圈或是366圈之後剛好會是地球公轉1圈嗎?……當然不是,所以才有了平年與閏年的機制來調整差距。

事實上,地球公轉1圈所需的時間大約等於地球自轉365.2422圈所需的時間。推算下去的話,地球在公轉四圈之後,地球上會過#{{365 \times 4}}#外加#{{0.2422 \times 4 = 365 \times 4 + 0.9688}}#天,這也就是為什麼每四年就要多1天出來。

然後又由於每四年多出來的時間不是完整的一天,如果直接補一天進去的話,一百年之後又會多出#{{(1 - 0.9688) \times {100 \over 4} = 0.78}}#天。所以又規定第100年不閏年,這樣的話一百年後只會少#{{0.22}}#天,差距變得比較小了。

繼續推算下去,四百年之後就會少#{{0.22 \times 4 = 0.88}}#天,快是完整的一天了,所以又規定第四百年是閏年,補1天回來。當然用這種方式,每四百年都會多#{{(1 - 0.88) = 0.12}}#天,若繼續依照這個邏輯,在三千二百年後會多出#{{0.12 \times 8 = 0.96}}#天,所以要規定第3200年不是閏年才行。不過目前公曆對於閏年的規則只有到四百年而已,且或許未來咱們的地球自轉會愈來愈慢也不一定,現階段不用去探討這麼遙遠的年份,意義不大。

寫程式判斷閏年

記住這個規則:「四年一閏;百年不閏,四百年再閏」。就可以很快地寫出如下的程式:

寫程式計算一個月有幾天

一月、三月、五月、七月、八月、十月、十二月是大月,有31天。四月、六月、九月、十一月是小月,有30天。平年的二月,有28天;閏年的二月,有29天。

總結以上,可以撰寫出如下的程式:

Year Helper

「Year Helper」是筆者開發的套件,提供判斷閏年、以及計算一個月或是一年有幾天的函數。包成套件就不用每次都貼一樣的程式碼了。

在Rust上使用Year Helper

Crates.io

Cargo.toml

year-helper = "*"
使用方法

year_helper這個crate提供is_leap_yearget_days_in_monthget_days_in_year三個函數。另外還有get_days_in_month_2get_days_in_year_2函數,來處理已知的閏年或平年。

let year = 2020;
let month = 2;

let leap_year = year_helper::is_leap_year(year);

let days_in_month = year_helper::get_days_in_month(year, month);
let days_in_year = year_helper::get_days_in_year(year);

// or use the following functions if the year has been determined whether it is a leap year
let days_in_month = year_helper::get_days_in_month_2(leap_year, month);
let days_in_year = year_helper::get_days_in_year_2(leap_year);

在JavaScript/TypeScript上使用Year Helper

npmjs.com

npm 安裝指令

npm install year-helper
使用方法
import { isLeapYear, getDaysInMonth, getDaysInYear } from "year-helper";

console.log(isLeapYear(2000));        // true
console.log(getDaysInMonth(2000, 2)); // 29
console.log(getDaysInYear(2000));     // 366

getDaysInMonthgetDaysInYear的第一個參數也可以傳入一個布林值來表示月份是否在已知的閏年下。

在網頁瀏覽器上使用Year Helper

網頁原始碼

展示頁面