zoukankan      html  css  js  c++  java
  • 基姆拉尔森计算公式 推导

    基姆拉尔森计算公式 推导

    需求:

    给定一个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
  • 相关阅读:
    Largest Rectangle in Histogram
    Valid Sudoku
    Set Matrix Zeroes
    Unique Paths
    Binary Tree Level Order Traversal II
    Binary Tree Level Order Traversal
    Path Sum II
    Path Sum
    Validate Binary Search Tree
    新手程序员 e
  • 原文地址:https://www.cnblogs.com/SeekHit/p/7498408.html
Copyright © 2011-2022 走看看