如何只根據日期計算對應的星期數


一、引子

最近想到一個問題,有些指針式手表除了指示時分秒的三針之外只有一個小的日歷口顯示當前日期,而對於上班族來講星期的概念可能更常用,那如何通過這個日期就推測出當天是星期幾呢?

這里其實蘊含着三個值,第一個是當前年份,一般而言年份這種周期比較長的很難弄錯,所以也不用特別注意;第二個是月份,相對於日期來講當前是處於哪個月還是較容易記住的;第三個是日期,這個對於日復一日的打工仔來說相對就不那么重要了,畢竟每周只要記住哪天是周幾就能愉快地上下班了,這個日期值是要以外在的形式提醒我們的。

二、計算公式

查了一下相應的算法,以蔡勒公式 (Zeller's Formula) 最為知名,該公式最早是由德國數學家克里斯蒂安·蔡勒 (Christian Zeller, 1822-1899) 在1886年推導出的。

W = (Y+[Y/4]+[C/4]-2*C+[(13*(M+1))/5]+D-1) mod 7

其中
W是所求當前日期對應的星期數,0表示周日,1-6表示對應的周一到周六。
Y是當前年份的后兩位,Y=year mod 100。
C 是當前年份的前兩位,C=year / 100。
M 是當前月份。
D 是當前日期。
mod 是取余操作。
[] 是高斯取整操作。

【注】

  1. 負數只能按數論中余數的定義求余。為方便計算可以加上一個7的整數倍,使它變為一個正數,然后再對7求余。
  2. 該公式使用於公歷(格里高利歷)的置閏規則。對於儒略歷則有所不同。

對推導過程及其歷史演變感興趣的可以看一看參考資料中的[4]和[6]。

三、應用舉例

簡單來講,就是利用前面提到的三個值進行計算,分別記作Y、M、D。

首先看年份,取當前年份的后兩位並記作 Y,Y=year mod 100,比如今年是2021年則Y=21。

然后看月份,這一步相對比較麻煩一些,分為平年和閏年兩種情況。
平年時月份-月份數對應關系分別為:1-6,2-2,3-2,4-5,5-0,6-3,7-5,8-1,9-4,10-6,11-2,12-4。
閏年時月份-月份數對應關系分別為:1-5,2-1,3-2,4-5,5-0,6-3,7-5,8-1,9-3,10-6,11-2,12-4。
閏年與平年的區別在於一月份和二月份,閏年時相當於把平年時此兩個月的月份數分別減一,其余不變。
可以利用如下的表盤來記憶。
image

接着看日期,直接就是日期本身,D=date。

現在利用這三個數值計算星期數,以2021-03-16這個日期為例

Y=21,對應數字為(21/4+21) mod 7=26 mod 7 = 5
M=3,對應數字為2
D=16,對應數字為16

然后三個值對應的數字相加再對其取余,(5+2+16) mod 7=2,表示當前日期為周二。

(全文完)


參考資料

[1] 怎樣快速根據日期推算星期 https://jingyan.baidu.com/article/ae97a646820186bbfd461d37.html

[2] Zeller's congruence https://en.wikipedia.org/wiki/Zeller's_congruence

[3] 蔡勒公式 https://blog.csdn.net/qq_42804678/article/details/82793438

[4] [轉載]1582年10月4日和1752年9月3日怎么了 https://www.cnblogs.com/igaoshang/articles/Date15821004.html

[5] 總天數以及星期幾的計算算法 https://www.cnblogs.com/igaoshang/p/DayOfWeek.html

[6] [轉載]蔡勒(Zeller)公式——計算任意一天是星期幾 https://www.cnblogs.com/igaoshang/articles/Zeller.html

本文作者 :phillee
發表日期 :2021年3月16日
本文鏈接https://www.cnblogs.com/phillee/p/14446046.html
版權聲明 :自由轉載-非商用-非衍生-保持署名(創意共享3.0許可協議/CC BY-NC-SA 3.0)。轉載請注明出處!
限於本人水平,如果文章和代碼有表述不當之處,還請不吝賜教。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM