某天是星期几的算法

几年前在看动漫电影《夏日大作战》时,一个场景是宅男主人公在车上心算妹子的出生日期是星期几,当时对这一技能十分好奇。不过人家是全国奥数队员,数字功底深厚,心算某一天是星期几根本就不算个事儿,我也就只能望而兴叹了。今天看到《Java语言程序设计》第3章的课后习题时,给出了一个计算某天是星期几的公式,这个公式被叫做“泽勒一致性”,由克里斯汀·泽勒发明。公式长这样:



公式中各个字母的含义是:

h: 是我们要计算的星期几

q: 是要计数某天的日期数,比如要计算2014年4月17日,q 就是17

m: 是某天所在的月份数

k: 是某天所在世纪的后两位年份,如:2014年4月17日,k就是14

j: 是某天所在世纪的世纪数,如:2014年4月17日,j就是20

下面我们来套下公式,看是不是能求出某天是星期几。

h = (17 + (26*(4+1)/10) + 14 + 14/4 + 20/4 + 5*20) % 7

h = 5

发现余数是5,但2014年4月17日是星期四。而这个算法余数结果与星期的对应关系是:0为星期六,1为星期天,2为星期一,3为星期二,4为星期三,5为星期四,6为星期五,6为星期六。所以,余数是5为星期四,看来算法是对。不过,我们还没对特殊的2月份做过测试呢。我们接着再做几组数据的测试:

2014年2月1日  --> 星期三,实际是星期六

2014年2月28日  --> 星期二,实际是星期五

2014年10月2日  --> 星期四,实际是星期四

2014年12月8日  --> 星期一,实际是星期一

1989年5月10日  --> 星期三,实际是星期三

1990年1月5日  --> 星期三,实际是星期五

上面6个日期计算的星期数,三个错误,三个正确。但只要日期是在2月份的全部歇菜,连1月份的也不对。原来泽勒一致性还有个规定:如果月份是1月或2月,月份数字要用13和14来代替,同时年份数字要改为去年的年份数字。如:2014年1月29日,实际被计算的年、月、日数字是:2013, 13, 29。根据这些规则,我们的Java代码如下:

import java.util.Scanner;

class  calculateDate
{
	public static void main(String[] args) 
	{
		Scanner s = new Scanner(System.in);

		System.out.print("Enter year: (e.g., 2008): ");
		int year = s.nextInt();
		
		System.out.print("Enter month: 1-12: ");
		int month = s.nextInt();

		System.out.print("Enter the day of the month: 1-31: ");
		int day = s.nextInt();

		int k = year % 100;
		int j = year / 100;

		// 处理1月、2月的日期
		if(month == 1)
		{
			month = 13;
			year = year - 1;
		}
		else if (month == 2)
		{
			month = 14;
			year = year 
		}

		int h = (day + (26*(month+1)/10) + k + k/4 + j/4 + 5*j) % 7;  // 泽勒一致性公式


		// 对余数做日期判断
		switch(h)
		{
			case 0:
				System.out.println("Day of the week is Sunday.");
			    break;
			case 1:
				System.out.println("Day of the week is Saturday.");
			    break;
			case 2:
				System.out.println("Day of the week is Monday.");
			    break;
			case 3:
				System.out.println("Day of the week is Tuesday.");
			    break;
			case 4:
				System.out.println("Day of the week is Wednesday.");
			    break;
			case 5:
				System.out.println("Day of the week is Thursday.");
			    break;
			case 6:
				System.out.println("Day of the week is Friday.");
			    break;
		}
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值