2013-2014学年第二学期《面向对象程序设计》课程设计报告题目:万年历系统专业:计算机科学与技术班级:姓名:学号:指导教师:成绩:计算机与信息工程系2014年6月6日目录1 设计内容及要求万年历,实际上就是记录一定时间范围内(比如100年或更多)的具体阳历或阴历的日期的年历,方便有需要的人查询使用。
在我设计的万年历中主要有:(1)使用图形用户界面来查询用用户所需的日期信息,符合日常软件使用规范。
(2)按月份查询,实现了显示查询1901~2100年某月所有日期的阴阳历对照。
(3)并且添加了重大节日与星座等信息,界面采用日常的星期与月份结合的格式,方便查看与使用。
(4)编写万年历的课程设计,是为了使同学们更加了解高级程序设计语言的结构,掌握基本的程序设计过程和技巧,掌握基本的分析问题和利用计算机求解问题的能力,具备初步的高级语言程序设计能力。
为后续各门计算机课程的学习和毕业设计打下坚实基础。
利用JAVA语言编写的万年历系统采用了多种JAVA语句来实现多种功能。
用户可以通过本程序的applet运行界面来查找一整年某月的农历和阳历,可以查找用户所想了解的某一天具体为星期几,并且可以看到一些重大节日的具体时间。
要求:满足设计万年历系统的目的,即当用户查询年份与月份时,系统就要将这一年的某一月份的阴历与阳历全部显示出来,并且附带这一月份的重大节日。
当用户随意改动年份或月份时系统自动显示与星期对应的日期。
用户点击日期时系统会显示具体星座信息。
2 概要设计(1)总天数的算法:首先用if语句判断定义年到输入年之间每一年是否为闰年,是闰年,该年的总天数为366,否则,为365。
然后判断输入的年是否为定义年,若是,令总天数S=1,否则,用累加法计算出定义年到输入年之间的总天数,再把输入年的一月到要输出的月份之间的天数累加起来,若该月是闰年中的月份并且该月还大于二月,再使总天数加1,否则,不加,既算出从定义年一月一日到输出年的该月一日的总天数。
(2)输出月份第一天为星期几的算法:使总天数除以7取余加2得几既为星期几,若是7,则为星期日。
(3)算出输出月份第一天为星期几的算法:算出输出月份第一天为星期几后,把该日期以前的位置用空格补上,并总该日起一次输出天数直到月底,该月中的天数加上该月一日为星期几的数字再除以7得0换行,即可完整的输出该月的日历。
(4)如果年份小于1900年则程序不予判断。
(5)公历与农历的换算。
公历年对应的农历数据,每年三字节,格式第一字节BIT7-4 位表示闰月月份,值为0 为无闰月,算法:日期+年份+所过闰年数+月较正数之和除7 的余数就是星期但如果是在闰年又不到3 月份上述之和要减一天再除7星期数为0。
阴历月份计算:4\6\9\11几个小月返回29天, 2月经过判断是否为闰年,选择返回28或29天,其余月份为大月,返回31天。
(6)系统时间的设置。
直接从系统得到时间,设置字体,背景,显示框架等等,绘图就好了。
(1)公历转农历流程图与运行界面①流程图图2 公历转农历流程图②运行界面图3 公农历运行图(2)时间调整程序流程图①流程图图4 时间调整流程图②运行界面图5 万年历运行图(1)本次程序设计共用了class MainCal extends JFrame implements,class CurrTimeLabel和class Lunar三个大类,用于绘制万年历,显示万年历的系统时间和完成农历与公历的换算。
这些类中又运用了许多函数,来完成月份的输出,背景的设置,特定日期的标注等等。
引用的类有:(2)农历的显示:要算出某年某月某日的农历日期,只能采用逐日递推的方式,这里以1900年1月31的日期为依据,它的农历日期为一九零零年大年初一,调用日历类可以算出所求日期与1900年1月31日相差多少天,设这个差值为offset,则用offset与1900~2100的农历年天数逐个相减,当offset<=0时,可以确定当前农历年份。
再用相减后得到的offset与得到的年份的农历月天数逐个相减,同理,当offset<=0时可以确定农历月份。
最后,Offset加上当前月份的天数就可以得到农历日期了,至此,阳历与农历的转换算法得以实现。
在排列阳历日期时,调用阳历与农历的转换算法得到相应农历日期,将对应阳历日期标签下的内容设为农历日期,主要源代码如下:public Lunar(Calendar cal) {int monCyl;int leapMonth = 0;Date baseDate = null;try {年1月31日 ");} catch (ParseException e) {}etText(sFtv[month-1][k++]);labelDay[a1+1][a2].setFont(new Font("黑体}if(k<=2)sFtvDay=sFtvDate[month-1][k];}4 设计结果与分析本程序经过设计并成功的调试了万年历系统的程序并且满足了万年历系统应该有的功能,例如:通过本程序的applet运行界面来查找一整年某月的农历和阳历,某一年某一月的日历,并且还是实现了重大节日的查询功能。
这样一来能更快的查询我们所需要的信息,程序调试结果如下图所示。
图6 万年历调试结果在设计此程序时,即使会满足我们设计的要求但同时也存在小缺陷:(1)此万年历的功能不够强大,调试后只能显示一些重大的节日而不能所有的节日都显示出来。
(2)设计这个万年历系统还有一个很大的遗憾就是没能添加二十四节气,这是美中不足的地方。
(3)万年历本应能查询一万年的日历,但在此程序中只是能查询一百多年的日历。
5 小结在这次课程设计中,主要是运用Java语言来编写,并可运用其他的技术。
在我的系统中,还采用了Swing控件、输入输出流等技术,而这些知识都是我们没有学过的,这就要求我们去查阅相关书籍。
正因为这样,才锻炼了我的自学能力,为以后的学习打下了基础。
此外,我还深刻感受到了面向对象语言中类库的强大功能,掌握了运用Java中的类实现某些基本功能,并学会了自己查询使用类的方法,为以后的面向对象语言的自学奠定了基础。
万年历系统程序的设计成功会让快节奏的社会上的感到方便,因为现在的社会离不开时间。
他们只需要呆在家里就可以清楚的知道某一天的日期。
并且对人们的工作也有所帮助,方便他们查询某年某月的资料以及制作报表。
因此,我认为万年历在今后的发展空间很大,如果包装成简易软件会有很高的利用价值,我们可以随时随地查阅。
致谢在这次JAVA高级语言课程设计中,我的老师和同学给了我及大的帮助。
特别是我的指导老师兼授课教师陈磊老师,在此,我对他们表示感谢。
感谢他们在我面对困难时给了我帮助和支持,,也感谢那些给我帮助的所有同学。
参考文献[1] 牛晓太.Java程序设计教程[M],北京:清华大学出版社,2013.[2] 朱福喜,傅建明.JAVA项目设计与开发范例[M],北京:电子工业出版社,2005.[3] 刘宝林.JAVA程序设计与案例[M].北京:高等教育出版社,2006.[5] Walter Savitch. Java完美编程[M]. 清华大学出版社.第三版[6] Philip Heller. 零起点Java应用编程[M]. 电子工业出版社[7] Deitlel. Java大学英语教程[M]. 电子工业出版社[9] 汪晓平. 精通Java网络编程[M]. 清华大学出版社. 2005[10] 孙一平,陈立. Java网络编程实例[M]. 清华大学出版社. 2004[11] 袁海燕,王文涛. Java实用程序设计[M]. 人民邮电出版社. 2005[12] 郑阿奇. Java实用教程[M]. 电子工业出版社. 2006[13] 罗依. Java Swing[M]. 清华大学出版社. 2006[14] 王涛,刘继光. Java2 API大全[M]. 电子工业出版社附录1:源程序public class MainCal extends JFrame implements ActionListener {private JLabel datas[][] = new JLabel[6][7];ddMouseListener(newList_MouseListener());}}return panel;}public void clear_Data() {etText("");if (j == 0 || j == 6)elsedatas[i][j].setForeground(null);}}public void initializtion_Data(Calendar calendar) {etText(day_str);}labelabendexOf("</font>"));String message = "<html><body><center>公元"年"月"日";.getSelectedItem().toString()) - 1, Integer.parseInt(day));Lunar lunar = new Lunar(calendar);message += "<br><font color=red>"message += " " +constellation(calendar)+ "</font><br>农历";月日";}}public void mouseExited(MouseEvent e) {yearCyl3:农历年与1864的相差数monCyl4:从1900年1月31日以来,闰月数* dayCyl5:与1900年1月31日相差的天数,再加40** @param cal* @return*/public Lunar(Calendar cal) {int monCyl;int leapMonth = 0;Date baseDate = null;try {年1月31日");} catch (ParseException e) {}// 求出和1900年1月31日相差的天数monCyl = 14;// 用offset减去每农历年的天数// 计算当天是农历第几天// i最终结果是农历的年份// offset是当年的第几天int iYear, daysOfYear = 0;for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) {daysOfYear = yearDays(iYear);offset -= daysOfYear;monCyl += 12;}if (offset < 0) {offset += daysOfYear;iYear--;monCyl -= 12;}// 农历年份year = iYear;leapMonth = leapMonth(iYear); // 闰哪个月,1-12leap = false;// 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天int iMonth, daysOfMonth = 0;for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) {// 闰月if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) {--iMonth;leap = true;daysOfMonth = leapDays(year);} elsedaysOfMonth = monthDays(year, iMonth);offset -= daysOfMonth;// 解除闰月if (leap && iMonth == (leapMonth + 1))leap = false;if (!leap)monCyl++;}// offset为0时,并且刚才计算的月份是闰月,要校正if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) { if (leap) {leap = false;} else {leap = true;--iMonth;--monCyl;}}// offset小于0时,也要校正if (offset < 0) {offset += daysOfMonth;--iMonth;--monCyl;}month = iMonth;day = offset + 1;public static String getChinaDayString(int day) {String chineseTen[] = { "初", "十", "廿", "卅" };int n = day % 10 == 0 9 : day % 10 - 1;if (day > 30)return "";if (day == 10)return "初十";elsereturn chineseTen[day / 10] + chineseNumber[n];}public String toString() {return /* cyclical() + "年" + */(leap "闰" : "")+ chineseNumber[month - 1] + "月" + getChinaDayString(day); }public String numeric_md() {// 返回阿拉伯数字的阴历日期String temp_day;String temp_mon;temp_mon = month < 10 "0" + month : "" + month;temp_day = day < 10 "0" + day : "" + day;return temp_mon + temp_day;}public String get_month() {// 返回阴历的月份return chineseNumber[month - 1];}public String get_date() {// 返回阴历的天return getChinaDayString(day);}public String get_Big_Or_Small() {// 返回的月份的大或小return Big_Or_Small[month - 1];}/*** This class is use to show current time,can auto refresh**/public class CurrTimeLabel extends JLabel{private static final long serialVersionUID = 1L;/*** Define a second*/private final static int ONE_SECOND=1000;/*** Timer Object,use to refresh label's text*/Timer timer=new Timer(ONE_SECOND,new ActionListener(){ public void actionPerformed(ActionEvent evt){setCurrTimeToText();}});/*** Constructor* @param strText*/public CurrTimeLabel(String strText){super(strText);}/*** Set current time to label's text**/private void setCurrTimeToText(){宋体}/*** Get current time,format is yyyy/MM/dd HH:mm:ss* @return current time String*/private String getCurrTime(){SimpleDateFormat fromatter=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");return strCurrTime;}}。