# 星期的計算

**星期的計算**是能够計算出某一指定日期是在一周中的哪一天的一类算法。多種數學算法均可計算出過去或未來某一指定日期，是屬於一周中的星期幾，包括判决日法则（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年为同周年，而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日是星期几：

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月份用斜体数字）行找到该数，对应到世纪行的数就是所求星期数。

| 日 期 | 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
 |
| 10 10 | 一 | 二 | 三 | 四 | 五 | 六 | 日 | 01 | 07 | 12 | 18 | *24* | **16**00 0**20**00 | **0** | **05**00 0**12**00 | **5** |
| 4 07 | 日 | 一 | 二 | 三 | 四 | 五 | 六 | 02 | *08* | 13 | 19 | 24
 |  | **06**00 0**13**00 | **6** |
| 9 012 | 六 | 日 | 一 | 二 | 三 | 四 | 五 | 03 | 08 | 14 | *20* | 25 | **17**00 0**21**00 | **1** | **07**00 0**14**00 | **0** |
| 6 | 五 | 六 | 日 | 一 | 二 | 三 | 四 | *04* | 09 | 15 | 20 | 26
 |  | **08**00 0 **15**00 | **1** |
| 20 3 011 | 四 | 五 | 六 | 日 | 一 | 二 | 三 | 04 | 10 | *16* | 21 | 27 | **18**00 0**22**00 | **2** | **09**00 0**02**00 | **2** |
| 8 | 三 | 四 | 五 | 六 | 日 | 一 | 二 | 05 | 11 | 16 | 22 | *00* |  | **10**00 0 **03**00 | **3** |
| 5 | 二 | 三 | 四 | 五 | 六 | 日 | 一 | 06 | *12* | 17 | 23 | 00 | **19**00 0**23**00 | **3** | **11**00 0**04**00 | **4** |

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日就是星期六。

## 高斯公式

格里历： WIKINIUM\_MATH\_PH\_0

儒略历： WIKINIUM\_MATH\_PH\_2

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月。具体的算法是這樣的：

 WIKINIUM\_MATH\_PH\_4
其中w代表星期

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

y代表年（兩位數）

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

d代表日

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

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

* 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) （页面存档备份，存于互联网档案馆）