星期的计算

星期的计算是能够计算出某一指定日期是在一周中的哪一天的一类算法。多种数学算法均可计算出过去或未来某一指定日期，是属于一周中的星期几，包括判决日法则（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)