基姆拉爾森計算公式 推導


基姆拉爾森計算公式 推導

需求:

給定一個xxxx-xx-xx日期,計算為星期幾。

設定

int y;  //年
int m;  //月
int d;  //日
int w;  //周幾

從 公元0年1月1日星期日 開始

推導

對於第一個月

    w = (d-1) % 7  --------- 公式(1)

對於年

  • 不考慮閏年
    在不考慮閏年的情況下,一年365天,365%7=1,就是說一年的第一天和最后一天是相同的。
    等價於,下一年的第一天星期幾是會比這一年的最后一天+1的。
    完善公式(1)
    w = (d-1 + y) % 7 --------- 公式(2)
  • 考慮閏年
    因為閏年會多出來一天,所以相當於,計算當前年份前面有多少個閏年,將日期數w額外+1
    計算閏年的公式為:
y/4 - y/100 + y/400

結合之前的公式1,2

w = [d-1+y + (y-1)/4-(y-1)/100+(y-1)/400] % 7 -----公式(3)

對於其它月份

  • 假設每個月都是28天
    因為28%7=0,也就是說每個月的w是相同的。
  • 按正常月份計算
    一月是31天,比28多3天,也就是說,2月的w值,是應該比1月按28計算的往后推遲3天。

三月的值,因為二月剛好28天,不影響,相當於還是推后3天。
以此類推。
因為12月已是最后一個月,所以不用考慮12月的誤差天數,同理,1月份的誤差天數是0,因為前面沒有月份影響它。

誤差表

誤差 累計 模7
1 3 0 0
2 0 3 3
3 3 3 3
4 2 6 6
5 3 8 1
6 2 11 4
7 3 13 6
8 3 16 2
9 2 19 5
10 3 21 0
11 2 24 3
12 - 26 5

如果用一個數組記錄就是

e[] = {0,3,3,6,1,4,6,2,5,0,3,5}

完善公式

w = [d-1+y + e[m-1] + (y-1)/4-(y-1)/100+(y-1)/400] % 7 --公式(4)
  • 將閏年的情況考慮進去
    如果是閏年的話,2月之后的都會順移一天
w = (d-1 + y + e[m-1] + (y-1)/4 - (y-1)/100 + (y-1)/400);
if(m>2 && (y%4==0 && y%100!=0 || y%400==0) && y!=0)
        ++w;
    w %= 7;

以上為基本推導過程

  • 數學大佬對公式進行了優化
    • W= (d+2m+3(m+1)/5+y+y/4-y/100+y/400+1)%7


免責聲明!

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



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