周日期的计算
在这个实验中,我们计算从1900年1月1日到2099年12月31日之间任意一天是星期几,在这段时间中,只有每4年一次的闰年需要调整日历(能够被100整除的年份一般不一定是闰年,但能够被400整除的年份一定是闰年)。
这个算法的一个基本特点是,要有一个按月调整的表,表中的每一个表项对应一个月份:
月份 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
调整 |
1 |
4 |
4 |
0 |
2 |
5 |
0 |
3 |
6 |
1 |
4 |
6 |
如果年份为闰年,并且是1月或者2月,则必须从调整值中减去1。
由于这里年份的日期从1900开始,因此年份需要减去1900,例如1906的年份为(1906-1900)=6,2001年的年份为101
算法:
(1) 计算下面数据的和
u 给定表格的月份调整
u 月份日期
u 年份
u 年份除以4得到的整数
(2)计算(1)中的和除以7得到的余数,余数就是周日期,0为周六,1为周日,2为周一。。。。。
余数 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
周几 |
周六 |
周日 |
周一 |
周二 |
周三 |
周四 |
周五 |
((年份-1900)/4+(年份-1900)+月份调整值+天数)mod 7
例如:1975年12月30日
((1975-1900)/4+(1975-1900)+6+30) mod 7 = 3
对于上面的表,可以知道为周二
代码如下:
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Random; public class Week { public static void main(String[] args) { int[][] week = { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }, { 1, 4, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6 } }; SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); String[] d = format.format(RandomDate()).split("-"); int year = Integer.parseInt(d[0]); int month = Integer.parseInt(d[1]); int day = Integer.parseInt(d[2]); System.out.println("日期为:" + year + "-" + month + "-" + day); int i = (year - 1900) / 4 + (year - 1900) + day + week[1][month - 1]; int dayofweek = i % 7; //闰年的调整 if (year % 100 == 0 && year % 400 == 0) { if (month == 1 || month == 2) dayofweek--; } else if (year % 100 != 0) { if (month == 1 || month == 2) dayofweek--; } if (dayofweek == 0) System.out.println("星期六"); else if (dayofweek == 1) System.out.println("星期天"); else if (dayofweek == 2) System.out.println("星期一"); else if (dayofweek == 3) System.out.println("星期二"); else if (dayofweek == 4) System.out.println("星期三"); else if (dayofweek == 5) System.out.println("星期四"); else if (dayofweek == 6) System.out.println("星期五"); } private static Date RandomDate() { Random rand = new Random(); Calendar cal = Calendar.getInstance(); cal.set(1900, 0, 1); long start = cal.getTimeInMillis(); cal.set(2099, 0, 1); long end = cal.getTimeInMillis(); Date d = new Date(start + (long) (rand.nextDouble() * (end - start))); return d; } }