星期的計算

**星期的計算**是能夠計算出某一指定日期是在一周中的哪一天的一類算法。多種數學算法均可計算出過去或未來某一指定日期，是屬於一周中的星期幾，包括判決日法則（Doomsday Rule），Babwani 公式等，但其實這些算法皆基於類似的機制相互變化而來，只是透過不同規則取得相同結果。

算法的典型應用，是計算某人的出生日期或某重大事件的發生日期，是在一周中的哪一天。

## 簡介

差不多所有星期算法的基礎皆可歸納如下：

1. 從一個已知的日子作為起始日，一般採用世紀的第一天，通過同餘 7 計算共過去了多少天。如將一周日子由 0 至 6 計算，結果將為一餘數，如使用 1 至 7 計算，則 7 將代替 0。
2. 查表或使用已知規則計算上面的起始日，即該世紀開始的星期數。
3. 查表或使用已知規則計算該年份開始的星期數。
4. 計算該月份開始的星期數。
5. 從該月份開始的計算該日的星期數。

由以上可得知，使用同餘 7 表示在計算中可剔除 7 的倍數，如此可把 7 當作 0、8 當作 1、9 當作 2、18 當作 4，如此類推。如果把星期日當作第 0 日，7 日後（第 7 日）亦是星期日，而第 18 日則會與第 4 日相同，為星期日後的 4 天，即星期四。一些算法把所有加數先行計算，然後把 7 的倍數剔除，而其他算法則在每一步皆剔除 7 的倍數。兩種做法皆可取，第一種做法較適用於計算機及電腦算法中，其他則較適用於心算。熟悉這些計算方法之後，可在腦內計算出來。

### 簡單的方法

把四個數加起來然後同餘 7 就是所求的星期數。這四個數分別是：

C：2 (3-(c mod4))（格里曆）、(4-c) mod7（儒略曆）或查世紀星期表

Y：(y mod28+[y mod28/4]) mod7（閏年 1、2 月份 Y-1）或查年份星期表

M：((3.4+(m-3) mod12×2.6) mod7（1、2 月份 M-1）或查月份星期表

D：d mod7、或查日期星期表

就是說 ——W=(C+Y+M+D) mod7

* 舉例
  * 舉例說明 1：2008 年 12 月 10 日

(6+3+5+3) mod7=3，即該日是星期三，其中 c=20、y=8、m=12、d=10

* * 舉例說明 2：2008 年 2 月 10 日

(6+2+3+3) mod7=0，即該日是星期日，其中 c=20、y=8、m=2、d=10

* * 舉例說明 3：1842 年 8 月 29 日

(2+3+2+1) mod7=1，即該日是星期一，其中 c=18、y=42、m=8、d=29

## 有用的概念

### 同周月

**同周月**是指那些第一天的星期數相同的月份。例如 9 月與 12 月是同周月，因為 9 月 1 日是星期幾 12 月 1 日也必定是星期幾。顯然，只有兩個月份之間相隔整數周，或恰好相隔 7 的倍數天時，這兩個月才是同周月。比如在平年時，2 月正好有 28 天，即 2 月與 3 月是同周月；而在閏年時，2 月變成了 29 天，那麼 2 月與 3 月就不是同周月了。下面是同周月的列表：

* 平年：
  * 1 月、10 月同
  * 2 月、3 月、11 月同
  * 4 月、7 月同
  * 5 月、6 月、8 月不相同
  * 9 月、12 月同
* 閏年：
  * 1 月、4 月、7 月同
  * 2 月、8 月同
  * 3 月、11 月同
  * 5 月、6 月、10 月不相同
  * 9 月、12 月總相同

注意，5 月與 6 月，不管是平年還是閏年，與其它任何月份都不是同周月。另外，在下面的月份查找表中，同周月由於開始於一周中的同一天，所以它們的數字（星期數）是相同的。

### 同周年

**同周年**類似於同周月，是指那些第一天的星期數相同的年份。每一年的第一天都有星期一到星期日 7 種可能，而閏年的 2 月 29 日會改變其後日期的星期數。所以，每一年的星期構成共有 14 種可能。（教會用於計算復活節日期的主日文字即共有 14 種表示法）

例如 2023 年是以星期日開始的平年，與 2017 年、2006 年及 1995 年為同周年；2020 年是以星期三開始的閏年，與 2014 年同樣開始於星期三，但與 2015 年同樣結束於星期四。

## 算法

以下算法適用於公曆。需要注意的是，算法中世紀、年、月的星期數都是指的該世紀、年、月**第 0 天**為星期幾，這樣的好處是在計算時只要直接將天數加上就可以了，而不必再減 1。例如，1900 年的第 0 天（即 1899 年 12 月 31 日）是星期天，還要加上 1 才是 1900 年第 1 天（即 1 月 1 日）的星期數，即星期一。

另一個需要注意的是，算法中每一步得到的數字，都是參照特定日期得到的**相對星期數**，即與特定參照日相差幾個星期數。只有把所有這些數字相加，再根據已知的參照日才得到實際的星期數。

算法的基本步驟如下：

* 計算世紀的相對星期數，一種辦法是在下方表格中直接查找；另一種辦法是依以下規則計算：將世紀數除以 4，用 3 減去所得的餘數，再將所得數字乘以 2。需要注意的是這裡的世紀數是實際年數的前兩位，而不是十九、二十世紀。
  * 例如對於 1800－1899 年，我們取世紀數為 18（而不是 19 世紀），18/4 餘 2，然後用 3 減 2 得 1，最後 1 乘以 2 得到 2。即 1800 年第 0 日為星期二。如果世紀年是閏年的話（如 2000 年），世紀的相對星期數不是世紀年的第 0 天而是第 1 天。
* 計算該年的相對星期數，即所要計算的該年第 0 天與該世紀第 0 天相差多少。每一平年有 365 天，即 52 個星期加 1 天，也就是說下一年的起始星期數是當前年起始星期數加 1；如果是閏年那麼還要額外加 1 天。這樣我們如果知道該世紀開始的星期數，那麼只要每過一年起始星期數加 1，如果是閏年就再額外加 1，這樣就可以得出該世紀中任何一年的相對星期數。
  * 例如 1978 年，參照 1900 年過去了 78 年，那麼對於每一個平年都要加 1，而這 78 年間共有 78/4=19 個閏年（這裡的餘數可以互略，因為余出的兩年絕不會是閏年），還要再加 19。那麼 1978 年的起始星期數就是：1900 年的起始星期數 0+78+19=97，再取同餘 7 之後，相當於 6。
  * 另一種計算方法是把上面的 78 年除以 12，先將所得的商數與餘數相加；然後用餘數再除以 4，所得商數也加入剛才的結果。也就是 78/12 得到商數為 6，餘數為 6，兩者相加得 12；然後剛才的餘數 6/4 得到商數 1，那麼最後的結果就是 12+1=13，取同餘 7 之後，相當於 6。
* 計算該月的相對星期數，即所要計算的月份的第 0 天與該年第 0 天相差多少。我們參照下面的月份表可以得到每個月起始日的相對星期數。顯然 1 月的星期數為 0，因為 1 月的第 0 天也是作為參照日的該年的第 0 天。下面的表格同時列出了閏年時的特殊情況，有些算法把閏年放到最後一步再考慮，即如果所要計算的日期是閏年的 1 月或 2 月，將所得數字減 1。兩種方法都可以，只要不重複計算即可。
* 計算該日的星期數，即所要計算的日期與該月第 0 天相差多少。顯然這個數字就是該日的日期數，如 1 月 22 日相對於 1 月第 0 天過去了 22 天，得到 22，取同餘 7 之後，相當於 1。

 
將上面所有步驟的相對星期數相加，再取同餘 7 就是實際的星期數了。

### 例子

如我們要計算 1982 年 4 月 24 日是星期幾：

1. 在世紀表格中查到 1900 所在世紀對應數字：0
2. 該年數為：82（即 82 個平年）
3. 82 除以 4，82/4=20.5，取整數部分：20（即有 20 個閏年）
4. 在月份表格中查到 4 月對應數字：6
5. 將上面所得數字與日期數 24 相加：0+82+20+6+24=132
6. 對 132 取同餘 7，即 132/7=18 餘 6
7. 在日期表中得到：6 即星期六

又一個例子，1783 年 9 月 18 日是星期幾：

1. 在世紀表格中查到 1700 所在世紀對應數字：4
2. 該年數為：83（即 83 個平年）
3. 83 除以 4，83/4=20.75，取整數部分：20（即有 20 個閏年）
4. 在月份表格中查到 9 月對應數字：5
5. 將上面所得數字與日期數 18 相加：4+83+20+5+18=130
6. 對 130 取同餘 7，即 130/7=18 餘 4
7. 在日期表中得到：4 即星期四

再一個例子，2054 年 6 月 19 日是星期幾：

1. 在世紀表格中查到 2000 所在世紀為：6
2. 該年數為：54（即 54 個平年）
3. 54 除以 4，54/4=13.5，取整數部分：13（即有 13 個閏年）
4. 在月份表格中查到 6 月對應數字：4
5. 將上面所得數字與日期數 19 相加：6+54+13+4+19=96
6. 對 96 取同餘 7，即 96/7=13 餘 5
7. 在日期表中得到：5 即星期五

### 世紀星期表

```
格里历
1752-1799     4     c mod4=1
1800-1899     2     c mod4=2
1900-1999     0     c mod4=3
2000-2099     6     c mod4=0
2100-2199     4
儒略历
0800-0899     3     c mod7=1
0900-0999     2     c mod7=2
1000-1099     1     c mod7=3
1100-1199     0     c mod7=4
1200-1299     6     c mod7=5
1300-1399     5     c mod7=6
1400-1499     4     c mod7=0
1500-1582     3
```

### 年份星期表

```
01 07 12 18 _24_     1
02 _08_ 13 19 24     2
03 08 14 _20_ 25     3
_04_ 09 15 20 26     4
04 10 _16_ 21 27     5
05 11 16 22 _00_     6
06 _12_ 17 23 00     0
闰年1、2月份年份y用斜体
```

### 月份星期表

```
01月         0 
02月         3 
03月         3     
04月         6     
05月         1     
06月         4     
07月         6     
08月         2
09月         5
10月         0
11月         3
12月         5
```

### 日期星期表

```
星期一    1     01 08 15 22 29
星期二    2     02 09 16 23 30
星期三    3     03 10 17 24 31
星期四    4     04 11 18 25
星期五    5     05 12 19 26
星期六    6     06 13 20 27
星期天    0     07 14 21 28
```

## 表格法

查星期：先找日和月的交叉數，然後在年（閏年 1、2 月份用斜體數字）行找到該數，對應到世紀行的數就是所求星期數。

1. 查 2000 年 1 月 1 日的星期：1 月 1 日的交叉數是「一」，_00_ 年斜體行的「一」往上對應到 0（2000）世紀行的是「六」，所以這一天是星期六。
2. 查 2000 年 12 月 31 日的星期：12 月 31 日的交叉數也是「一」，00 年非斜體行的「一」往上對應到世紀行的是「日」，所以這一天是星期天。
3. 查 1855 年 2 月 23 日的星期：2 月 23 日的交叉數是「五」，27（55 mod 28）年行和 2（18 mod 4）世紀行同行，所以這一天是星期五。

查主日字母：世紀行「日」所在的列為主日字母世紀列，年份行對應到該列的數字就是該年的主日字母，一為 A、二為 B、三為 C、四為 D、五為 E、六為 F、日為 G。

1. 查 2013 年的主日字母：本世紀（20 或 0）為第一行（上），所對應的世紀列為最後一列（右），13 年對應到該列的「六」，所以主日字母是 F。
2. 查 1893 年的主日字母：本世紀行的「日」在第四列，93 mod 28 = 9 年對應該列的「一」，所以主日字母是 A。

查判決日（Doomsday）星期數：年份行的「三」對應到世紀行的數就是 Doomsday。

1. 查 2013 年的 Doomsday：13 年的「三」對應到世紀行（20 或 0）的數是「四」，所以 Doomsday 是星期四。
2. 查 1809 年的 Doomsday：9 年的「三」對應到世紀行的數是「二」，所以 Doomsday 是星期二。

此外，主日字母（DL）和判決日（DD）存在著這樣的關係：DL + DD = C（3）。如 2013 年的主日字母是 F，那判決日的星期數 DD = 3（C）- 6（F）mod 7 = 4（星期四）。

## 心算法

心算時為方便記憶，一個簡單的方法就是把一年的起始日想像成 3 月 1 日而不是 1 月 1 日（就像古羅馬曆一樣），這樣閏年的 2 月 29 日就變成了每年的最後一天，而不是在一年的中間。這樣，計算星期時的標準**第 0 日**就變成了 2 月的最後一天。下面就會看到，這樣計算時很方便記憶。

### 判決日

* 4 月 4 日，6 月 6 日，8 月 8 日，10 月 10 日，12 月 12 日都與第 0 日（2 月最後一天）的星期數相同。
* 5 月 9 日，9 月 5 日也與第 0 日相同。（為方便記憶，這些日子稱為「朝九晚五」）。
* 7 月 11 日，11 月 7 日也與第 0 日相同。 （為方便記憶，這些日子稱為「便利商店 7-11」） 。

這些日子在**判決日法則**中被稱作**判決日**，與心算的過程類似，可幫助計算。

另一好處是 1 月和 2 月的計算也相對簡單了，只要記住 1 月 9 日（或 1 月 16 日）和 2 月 6 日與**上一年**的判決日（2 月最後一天）星期數相同就可以了。下面列出了每個月中便於記憶的判決日：

 

```
月          +5 月         -5 月         +10 月
4月4日      9月5日                       2月6日
6月6日      11月7日 
8月8日      1月9日　       3月7日
10月10日                　5月9日
12月12日                　7月11日
```

所以只要確定每一年的第 0 日（2 月最後一天）是星期幾，參照上方列出的具有相同星期數的**判決日**，即可快速推算某天是星期幾。

### 年數的計算

確定每一年的第 0 日是星期幾很簡單：

1. 首先記住 2000 年第 0 日（2 月最後一天）是星期二。每 100 年的第 0 日的星期數按下面規律變化：星期二（Tuesday），星期日（Sunday），星期五（Friday），星期三（Wednesday），星期二（Tuesday），星期日（Sunday），星期五（Friday），星期三（Wednesday）…… 如此循環往復。（一個幫助記憶的方法就是取英文字的首字母（T.S.F.W），將它們組成一句話：Too Sunny For Walk）按此規律，2100 年**第 0 日**是星期日，1900 年是星期三。
2. 此外，每過一個平年，第 0 日的星期數加 1，每過一個閏年，第 0 日的星期數加 2。這樣每過 12 年，第 0 日的星期數就加 1。比如 2000 年是星期二，2012 年就是星期三，2024 年就是星期四。另外一個值得記住的是，每相隔 28 年，只要相隔的兩年在一個世紀內，或者跨過 2000 年，那麼它們的第 0 日都在一個星期。（比如 1972 年與 2028 年是一樣的。）

### 例子

比如我們要計算 2017 年 6 月 3 日是星期幾。首先想到 2000 年第 0 日是星期二，那麼 12 年後的 2012 年是星期三，2013 年是星期四，2014 年是星期五，2015 年是星期六，2016 年是星期一（因為是閏年），2017 年第 0 日就是星期二。然後想到 6 月的判決日 6 月 6 日也是星期二，那麼 3 天前的 6 月 3 日就是星期六。

## 高斯公式

格里曆： $w=(d+[2.6m-0.2]+5(y\operatorname {mod} 4)+3y+5(c\operatorname {mod} 4))\operatorname {mod} 7$ 
儒略曆： $w=(d+[2.6m-2.2]+5(y\operatorname {mod} 4)+3y+6(c\operatorname {mod} 7))\operatorname {mod} 7$ 

　
: d = 日期

　
: m = 月數 - 2（1 月為 11 月，2 月為 12 月）

　
: y = 年數後 2 位（1、2 月份 y - 1）

　
: c = 世紀數 - 1

### 例子

計算 2000 年 1 月 1 日的星期，這一日期應視為 1999 年的 11 月 1 日。

　
: d = 1

　
: [2.6 x 11 - 0.2] = 28 mod 7 = 0

　
: 5(99 mod 4) = 5 x 3 = 15 mod 7 = 1

　
: 3 x 99 mod 7 = 3 x 1 = 3

　
: 5(19 mod 4) = 5 x 3 = 15 mod 7 = 1

* w = 1 + 0 + 1 + 3 + 1 = 6 = 星期六

計算 2000 年 12 月 31 日的星期，這一日期應視為該年的 10 月 31 日。

　
: d = 31 mod 7 = 3

　
: [2.6 x 10 - 0.2] = 26 mod 7 = 4

　
: 5(0 mod 4) = 5 x 0 = 0

　
: 3 x 0 = 0

　
: 5(20 mod 4) = 5 x 0 = 0

* w = 3 + 4 = 7 mod 7 = 0 星期日

計算 1777 年 4 月 30 日的星期，這一日期應視為該年的 2 月 30 日。

　
: d = 30 mod 7 = 2

　
: [2.6 × 2 - 0.2] = 5

　
: 5(77 mod 4) = 5 × 1 = 5

　
: 3 × 77 mod 7 = 3 × 0 = 0

　
: 5(17 mod 4) = 5 × 1 = 5

* w = 2 + 5 + 5 + 0 + 5 = 17 mod 7 = 3 = 星期三

計算 1582 年 10 月 4 日的星期，這一日期應視為該年的 8 月 4 日。

　
: d = 4

　
: [2.6 × 8 – 2.2] = 4

　
: 5(82 mod 4) = 5 × 2 mod 7 = 3

　
: 3 × 82 mod 7 = 3 × 5 mod 7 = 1

　
: 6(15 mod 7) = 6 × 1 = 6

* w = 4 + 4 + 3 + 1 + 6 mod 7 = 4 = 星期四

計算 BC1（0）年 1 月 1 日的星期，這一日期應視為前一年的 11 月 1 日。

　
: d = 1

　
: [2.6 × 11 – 2.2] = 5

　
: 5(0-1 mod 4) = 5 × 3 mod 7 = 1

　
: 3 × (0-1) = -3 mod 7 = 4

　
: 6(0 mod 7) = 6 × 0 = 0

* w = 1 + 5 + 1 + 4 + 0 mod 7 = 4 = 星期四

## Babwani 公式

2004 年 11 月，巴布瓦尼（Babwani）在倫敦數學學報（Mathematical Gazette）上發表了一種新的星期計算法。他的這種新方法相對於其它方法更簡單，而且不僅可用於計算星期數，更可以在星期、日期、月份、年份中已知任意三者時，計算剩下的未知者。

公式：w = (⌊5y/4⌋ + m + d - 2 (c mod 4) + 7) mod 7

```
其中w=1=星期日
c、y、和d=其它算法
m=月份星期表
⌊5y/4⌋=其它公式的y+⌊y/4⌋
-2(c mod 4)+7=1+6-2(c mod 4)=1+其它算法的2(3-(c mod 4)，所以1代表的不是星期一而是星期日。
```

## 蔡勒公式

在蔡勒算法中，每一年被假設從 3 月開始，月份標號從 3（3 月）到 14（二月），即 1995 年 1 月被認為是 1994 年 13 月。具體的算法是這樣的：

　
: $w=\left(y+[{\frac {y}{4}}]+[{\frac {c}{4}}]-2c+[{\frac {26(m+1)}{10}}]+d-1\right)\mod 7$

其中 w 代表星期

c 代表世紀數減 1 (年份前兩位數)

y 代表年（兩位數）

m 代表月（m 大於等於 3，小於等於 14，即在蔡勒公式中，某年的 1、2 月要看作上一年的 13、14 月來計算，比如 2003 年 1 月 1 日要看作 2002 年的 13 月 1 日來計算）

d 代表日

[ ] 稱作高斯符號，代表取整，即只要整數部份。

mod 代表同餘（這裡代表括號裡除以 7 後的餘數）

## 主日字母

每一年的星期數也可以根據主日字母確定。基督教教歷上常用 A-G 七個字母來標示某一年的星期日（主日）是在第幾天，如 1 月 3 日為星期日，那麼該年的主日字母就是 C。該年的主日字母確定了，那麼每一天就按順序被分配給相應的字母。此一方法據說最早古羅馬人就有使用，後來常用於基督教上確定復活節日期的一種計算辦法。在這一系統中，閏年的 2 月 29 日沒有主日字母，這就使得 2 月 29 日之後的星期日與此前的星期日的主日字母不一致，所以閏年的主日字母都有兩個。

## 參見

* ISO 8601
* 判決日法則
* 蔡勒公式
* 萬年曆
* 儒略日

## 資料來源

* 青衣北網 （頁面存檔備份，存於網際網路檔案館）
* World records for mentally calculating the day of the week in the Gregorian Calendar （頁面存檔備份，存於網際網路檔案館）
* National records for finding Calendar Dates （頁面存檔備份，存於網際網路檔案館）
* World Ranking of Memoriad Mental Calendar Dates (all competitions combined) （頁面存檔備份，存於網際網路檔案館）