Java 计算一个月的休息日;打印输出一个月的日历表;计算两个日期之间相隔的天数

  1. 问题描述
    在这里插入图片描述
  2. 解决思路
        该实验需要解决的难点有:(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,循环体中,每满足一个条件便自身加一实现。
  3. 程序代码
    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+"天");
    }
}
  1. 遇到的问题

(2)问题描述:当输入月份不为2时,不能输出正常的月份。由此可知在进行月份的存储时出错。
在这里插入图片描述

解决方法:日期格式不正确,MM表示月份,区分大小写;将mm改成MM即可。

注意: 对于SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);后的格式为yyyy-MM-dd HH:mm:ss,区分大小写,否则在存储日期时容易出错。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值