一书中解答:
public static String day (int year, int month, int day){
       if(m == 1 || m == 2){
              m += 12;
              year--;
       }
       int week = day + 2*month + 3*(month + 1)/5 + year + year/4 - year/100 + year/400 + 1;
       week = week % 7;
       String w = "日一二三四五六".substring(week, week+1);
       return w;
}
谁能给我解释一下其中算法的原理??

解决方案 »

  1.   

    这是蔡勒(Zeller)公式的演化,楼主自己去找找看吧.
      

  2.   

    被LZ激起兴趣,写多了,愿意看就看与其说这是java问题,不如说是数学问题、历史问题。首先要明白两个事实:
    1、通常,每过一年,相同日期的是星期几就要后退1天;
    2、公元元年1月1日是星期一(实行“星期制”后规定的)所以这个算法是以每年的元月1日为参考点,而每年的元月1日是星期几又是以公元元年元月1日为参考的。
    语句:int week = day + 2*month + 3*(month + 1)/5 + year + year/4 - year/100 + year/400 + 1就是计算某年某月某日距离这一年的1月1日一共有多少天的。当然,如果恰好找到是7的倍数,可以不写上去。分析这个语句,可以分成三部分:day、year + year/4 - year/100 + year/400以及 2*month + 3*(month + 1)/5
    ①day这个好理解
    ②year距离公元元年多少年,后面的year/4 - year/100 + year/400是修正闰年带来的影响,自己理解,所以上述事实1是用“通常”表示不考虑闰年,而这里就考虑了闰年了。
    ③这个复杂,先说为什么有2*month。除2月外,一个月至少有30天,比7*4=28多两天,所以要2*月数来获得除7之后的余数。之后的3*(month + 1)/5,先看下面:
    月:1、2、3、4、5、6、7、8、9、10、11、12
    值:1、-2、1、0、1、0、1、1、0、1 、0 、1
    这个“值”表示这个月的天数与30比较,多则为正,少则为负。上述的②,已经考虑了闰月的影响了,所以这里2月的天数是一般的28天。“月-值”关系可以看出,1、2月很特别,所以算法的作者用if语句将其排除在外:如果1或2月,则月数+12,就是加1年了,后面又减了一年,等于没加。
    再看5-7月和和8-12月,都是没5个月就加3天,所以是3/5。至于为什么是month+1,以及独立于三个部分之外的的“+1”,大概是修正计算③的吧。这里没什么原理的,是原作者经过无数次微调而得出的结果吧。其实这里的算法复杂了,参考http://zhoushijingguo.blog.163.com/blog/static/15359663620107203021873/可以知道,只要Math.floor()就可以了。
      

  3.   

    good, I get it!!!