给定一个日期,问这个日期是星期几。
罗马教皇格里高利13世在1582年组织了一批天文学家,根据哥白尼日心说计算出来的数据,对儒略历作了修改。将1582年10月5日到14日之间的10天宣布撤销,继10月4日之后为10月15日。后来人们将这一新的历法称为“格里高利历”,也就是今天世界上通用的历法。不同国家取消旧历法启用新历法的年代不同,导致蔡勒公式的不同版本。
第一个方法书计算这个日期与今天的距离X,假设今天是星期y,那么给定日期是星期((y - X) % 7 + 7) % 7(给定日期是今天之前),或者星期 (y + X) % 7 + 1(给定日期是未来的日期)。
第二个方法是直接使用蔡勒公式:
Week = (Day + 2 X Month + 3 X (Month + 1) / 5) + Year + Year / 4 - Year / 100 + Year / 400) % 7
当日期在1752年9月3日之前时:
Week = (Day + 2 X Month + 3 X (Month + 1) / 5) + Year + Year / 4 + 5) % 7
1 int watDay(int d, int m, int y) {
2 int ret;
3 if (m == 1 || m == 2) {
4 m += 12;
5 y--;
6 }
7 if ((y < 1752) || (y == 1752 && m < 9) || (y == 1752 && m == 9 && d == 3))
8 ret = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 + 5) % 7;
9 else
10 ret = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7;
11 return ret;
12 }日期相隔天数计算
给定两个日期A,B,求A,B间隔多少天。
计算公元元年到A和B分别有多少天,然后两个值相减即可。下面的代码不考虑公元前以及历史上的日历调整。
1 const int days = 365;
2 const int s[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
3
4 bool Isleep(int y) {
5 if (y % 400 == 0 || y % 100 && y % 4 == 0) return 1;
6 return 0;
7 }
8 int leap(int y) {
9 if (!y) return 0;
10 return y / 4 - y / 100 + y / 400;
11 }
12 int calc(int day, int mon, int year) {
13 int res = (year - 1) * days + leap(year - 1);
14 for (int i = 1; i < mon; i++) {
15 res += s[i];
16 }
17 if (Isleep(year) && mon > 2) res++;
18 res += day;
19 return res;
20 }
21 int countDay(int da, int ma, int ya, int db, int mb, int yb) {
22 return abs(calc(da, ma, ya) - calc(db, mb, yb));
23 }