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
  • 相关阅读:
    服务器响应状态码
    细说同域-同父域-跨域
    细说Ajax跨域
    为SQL缓存通知启用数据库
    使用PATINDEX()判断含有[A-Z]、[a-z]、[0-9]之外的字符
    记一次SQLServer的分页优化兼谈谈使用Row_Number()分页存在的问题
    谈谈如何在面试中发掘程序猿的核心竞争力
    “属性”与“特性”区别
    【转】安卓手机无法安装软件的原因总结
    【转】自学android半年,已从.net转型成android程序员
  • 原文地址:https://www.cnblogs.com/SeekHit/p/7498408.html
Copyright © 2011-2022 走看看