- 问题描述
- 解决思路
该实验需要解决的难点有:(1)如何确定日历月份前面的空格数;(2)如何确定休息日的日期;(3)如何求得两个已知日期之间的相隔天数。
对于(1)日历月份前的空格数可以通过计算1900年1月1日至该月1月的总天数,然后对7求余得到;对于(2)可以通过求得对应日期至2020年02月02日(规定该日为起始休息日)相隔的天数,对4取余得到(相隔三天休息一天);对于(3)可以采用SimpleDateFormat()方法、Date()方法和getTime()()方法获取时间,然后通过时间相减得到时间差,时间差是以毫秒为单位的,所以需要除于(1000 * 60 * 60 * 24)得到。
实验之前需要将所有思路理顺,理顺思路后,编写代码就容易实现了很多。在这里分享下自己看题目后的思路:(1)该实验实质上是输出一个月的日历表,输出日历表需要知道日历前需要输出的空格总数,通过查找资料后确定求空格总数的方法blankSum()。(2)但实现该方法需要求得时间间隔总天数,所以进一步设计出计算两个日期之间的时间间隔countDaysBetween()方法。(3)该方法还可以用于计算工作日:将一个日期与起始休息日的时间间隔求出来,对4取余,如果为0则判断为休息日。(4)打印日历表还需要知道该月份的总天数,在这里可以使用判断语句if-else if-…-else实现,通过判断大月或者小月以及是否是闰年从而确定月份总天数。(5)最后使用循环语句,从1开始至月份的最后一天,在循环体中判断是否是休息日(如果是休息日需要加中括号[])以及是否是周六(如果是周六需要进行换行;判断是否是周六可以通过空格数+i,然后对7取余,如果等于0则表示是周六)。(6)对于休息总天数和在周末的休息天总数,可以定义两个int型变量,初始值为0,循环体中,每满足一个条件便自身加一实现。 - 程序代码
Dao.java用于存储实现一些功能的方法,提高代码的可读性。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class Dao {
/**
* 计算两个日期之间的时间间隔
* @param startYMD 起始时间,默认2020-02-02
* @param endYMD 结束时间
* @return 两个时间的间隔天数
* @throws ParseException
*/
public long countDaysBetween(String startYMD,String endYMD) throws ParseException {
long daysBetween = 0;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date startDate = sdf.parse(startYMD);
Date endDate = sdf.parse(endYMD);
daysBetween = (endDate.getTime() - startDate.getTime())/(1000 * 60 * 60 * 24);
/*Calendar cal = Calendar.getInstance();
cal.setTime(sdf.parse(startYMD));
long startTime = cal.getTimeInMillis();
cal.setTime(sdf.parse(endYMD));
long endTime = cal.getTimeInMillis();
daysBetween = (endTime - startTime)/(1000 * 60 * 60 * 24);*/
return daysBetween;
}
/**
* 计算需打印输出的月份前面需要输出的空格总数
* 思路:1900年至该月间隔的天数总和sum+1,对7取余得到空格总数blankSum
* @param endYM 用户输入的年月
* @return 需输出的空格总数
*/
public long blankSum(String endYM) throws ParseException {
long blankSum = 0;
String endYMD = endYM + "-01";
String startYMD = "1900-01-01";
long sum = countDaysBetween(startYMD,endYMD);
blankSum = (sum + 1) % 7;
return blankSum;
}
/**
* 返回对应月份的天数
* @param year 用户输入的年份
* @param month 用户输入的月份
* @return 该月份的天数
*/
public int daysMax(int year,int month){
int daysMax = 0;
//大月有31天
if(month==1 || month==3 || month==5 || month==7 || month==8 ||month==10 || month==12){
daysMax = 31;
}
//小月(除了2月)有30天
else if (month==4 || month==6 || month==9 || month==11){
daysMax = 30;
}
//闰年的2月有29天
else if (month==2 && ((year%4==0 && year%100!=0) || (year%400==0))){
daysMax = 29;
}
//平年的2月有28天
else{
daysMax =28;
}
return daysMax;
}
}
DayOff.java为主类,通过调用Dao方法实现对应的功能并打印输出
/**
* 2021-03-03
*/
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class DayOff {
private static Dao dao = new Dao();
public static void main(String[] args) throws ParseException {
Scanner input = new Scanner(System.in);
System.out.println("请输入年:");
int intYear = input.nextInt();
System.out.println("请输入月:");
int intMonth = input.nextInt();
String endY = Integer.toString(intYear);
String endM = Integer.toString(intMonth);
String endYM = endY + "-" + endM;
String startYMD = "2020-02-02";
long blankSum = dao.blankSum(endYM);//需打印的空格数
int daysMax = dao.daysMax(intYear,intMonth);
int dayOffSum = 0;//统计该月的休息天总数
int dayOffInWeekend = 0;//统计该月在周末的休息天总数
System.out.println("星期日\t星期一\t星期二\t星期三\t星期四\t星期五\t星期六\t");
//打印输出空格
for (int i=0;i<blankSum;i++){
System.out.print(" \t\t");
}
//顺序打印日期
for(int i=1;i<=daysMax;i++){
String endD = Integer.toString(i);
String endYMD = endYM + "-" + endD;
long daysBetween = dao.countDaysBetween(startYMD,endYMD);
//该天是休息日并且是星期六(需要进行换行输出)
if ((i+blankSum)%7==0 && daysBetween%4==0){
System.out.println("["+i+"]\t");
dayOffSum++;
}
//该天是休息日但不是星期六(不需要换行输出)
else if ((i+blankSum)%7!=0 && daysBetween%4==0){
System.out.print("["+i+"]\t");
dayOffSum++;
}
//该天不是休息日但是是星期六(需要换行输出)
else if ((i+blankSum)%7==0 && daysBetween%4!=0){
System.out.println(i+"\t\t");
}
//该天不是休息日也不是星期六(不需要换行输出)
else{
System.out.print(i+"\t\t");
}
//统计休息日在周末的天数
if (((i+blankSum)%7==0 || (i+blankSum)%7==1) && daysBetween%4==0){
dayOffInWeekend++;
}
}
System.out.println();
System.out.println("本月休息天数有:"+dayOffSum+"天");
System.out.println("本月轮到周末休息天数是"+dayOffInWeekend+"天");
}
}
- 遇到的问题
(2)问题描述:当输入月份不为2时,不能输出正常的月份。由此可知在进行月份的存储时出错。
解决方法:日期格式不正确,MM表示月份,区分大小写;将mm改成MM即可。
注意: 对于SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);后的格式为yyyy-MM-dd HH:mm:ss,区分大小写,否则在存储日期时容易出错。