星期的計算

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

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

## 簡介

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

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

由以上可得知，使用同餘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年為同周年，而2027年是以星期五開始的平年，與2021年、2010年及1999年為同周年。

2020年是以星期三開始的閏年，與2014年同樣開始於星期三，但與2015年同樣結束於星期四；2024年是以星期一開始的閏年，與2018年同樣開始於星期一，但與2019年同樣結束於星期二；而2032年是以星期四開始的閏年，與2026年同樣開始於星期四，但與2027年同樣結束於星期五。

## 演算法

以下演算法適用於公曆。需要注意的是，演算法中世紀、年、月的星期數都是指的該世紀、年、月第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日是星期幾：

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

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

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

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

- 在世紀表格中查到2000所在世紀為：6
- 該年數為：54（即54個平年）
- 54除以4，54/4=13.5，取整數部分：13（即有13個閏年）
- 在月份表格中查到6月對應數字：4
- 將上面所得數字與日期數19相加：6+54+13+4+19=96
- 對96取同餘7，即96/7=13餘5
- 在日期表中得到：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月份用斜體數字）行找到該數，對應到世紀行的數就是所求星期數。

日 期｜01｜02｜03｜04｜05｜06｜07

08｜09｜10｜11｜12｜13｜14

15｜16｜17｜18｜19｜20｜21

22｜23｜24｜25｜26｜27｜28

月 份｜29｜30｜31｜年份 modulo 28｜格里曆世紀 mod 4｜儒略曆世紀 mod 7

1 10｜一｜二｜三｜四｜五｜六｜日｜01｜07｜12｜18｜24｜1600 2000｜0｜0500 1200｜5

4 7｜日｜一｜二｜三｜四｜五｜六｜02｜08｜13｜19｜24｜0600 1300｜6

9 12｜六｜日｜一｜二｜三｜四｜五｜03｜08｜14｜20｜25｜1700 2100｜1｜0700 1400｜0

6｜五｜六｜日｜一｜二｜三｜四｜04｜09｜15｜20｜26｜0800 1500｜1

2 3 11｜四｜五｜六｜日｜一｜二｜三｜04｜10｜16｜21｜27｜1800 2200｜2｜0900 0200｜2

8｜三｜四｜五｜六｜日｜一｜二｜05｜11｜16｜22｜00｜1000 0300｜3

5｜二｜三｜四｜五｜六｜日｜一｜06｜12｜17｜23｜00｜1900 2300｜3｜1100 0400｜4

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

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

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

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

- 查2013年的Doomsday：13年的「三」對應到世紀行（20或0）的數是「四」，所以Doomsday是星期四。
- 查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日是星期幾很簡單：

- 首先記住2000年第0日（2月最後一天）是星期二。每100年的第0日的星期數按下面規律變化：星期二（Tuesday），星期日（Sunday），星期五（Friday），星期三（Wednesday），星期二（Tuesday），星期日（Sunday），星期五（Friday），星期三（Wednesday）……如此循環往復。（一個幫助記憶的方法就是取英文字的首字母（T.S.F.W），將它們組成一句話：Too Sunny For Walk）按此規律，2100年第0日是星期日，1900年是星期三。
- 此外，每過一個平年，第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後的餘數）

## 資料來源

- 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)