Java日历类Calendar练习——寻找休息日并打印日历

本文介绍了如何使用Java的Calendar类编写一个程序,根据用户输入的年和月,以日历形式展示休息日,并统计休息日总数。程序处理了输入错误,限制日期范围在2020年2月以后,利用日历API计算日期差,确定休息日,以及打印日历的过程。
摘要由CSDN通过智能技术生成

一、任务概述

某公司软件开发工程师孙工,作息规律为上三天班,休息一天,经常不确定休息日是否周末,为此,请你开发一个程序,当孙工输入年及月,以日历方式显示对应月份的休息日,用中括号进行标记.同时,统计出本月有几天休息,轮到周末休息有几天.(注:首次休息日是 2020 年 2 月 2 日)
代码运行结果
此习题来自 开课吧:《新职课JavaEE软件开发工程师》课程
第四章:Java核心类库
第2节:常用类库

二、日历类Calendar

1、getInstance()

创建Calendar类的实例对象时,一般不采用构造方法,而是使用Calendar.getInstance()方法,使用默认时区和区域设置获取日历对象。

Calendar calendar = Calendar.getInstance();

此对象中的时间为默认的系统当前日期与时间。

2、set()与get()

创建Calendar类的对象后,通过set()与get()方法对其包含的日期和时间属性进行设置和获取。

calendar.set(Calendar.YEAR, 2098);
// 给月份赋值时,0代表1月,1代表2月,11代表12月
calendar.set(Calendar.MONTH, 0);
System.out.println(calendar.getTime());
System.out.println(calendar.getTimeInMills());

getTime()返回值为Date类型的标准格式日期
在这里插入图片描述
getTimeInMills()返回 long类型的时间戳,单位为毫秒
在这里插入图片描述

三、思路梳理

1、让用户按需求输入日期

a、InputMismatchException

为了方便进行之后的赋值和运算,我们希望用户输入int类型的年份和月份,所以需要try catch InputMismatchException,当用户输入的类型不符时,需要提示用户重新输入,来确保程序正常执行

b、日期限定

因为需求中要求用户输入的日期不早于2020年2月,所以需要在用户输入日期时进行判断

当用户输入的年份小于2020时直接提示用户重新输入,当等于2020时,需进一步判断月份是否为1月份。可以写两个方法,分别引导用户输入满足需求的年份和月份。

2、打印日历

a、获取用户输入的月份的天数

我们想打印用户输入的月份的日历,首先想到循环,从1号打印到月末最后一天,那么首先要知道用户输入的那个月有多少天。

既然需求中我们已经让用户输入了年月,并创建了Calendar对象,那么就不要再去使用原始的switch手动判断,一三五七八十腊返回天数的办法。

Calendar类中为我们提供了getActualMaximum(int field)方法,获取field可能的最大值。

当我们传入的field为DAY_OF_MONTH时,可以获取用户输入的月中总共有多少天

int days = calendarInput.getActualMaximum(Calendar.DAY_OF_MONTH);

b、计算日期差

知道了该月总共有多少天之后,我们还要知道该月1号从什么位置开始打印,即:需要知道1号为周几。

我们已知2020年2月1号为周六,则可以通过两个时期的时间差对7取余,来判断用户输入的月份中1号为周几。

同时我们知道时期差之后,对4取余,可以用于判断休息日。

所以我们先要计算两个日期的差值天数,可以用两个日期的时间戳做差的方式计算。

c、获取用户输入月中1号为周几

知道日期差之后,将差值对7取余,则可以判断用户输入的月份中1号为周几。

已知2020年2月1号为周六,当余0时,输入月1号也为周六,该周的最后一天。

余1时日期错后一天,为周日,该周的第一天。

余2时继续错后两天,为周一,该周的第二天,其余同理。

综上规律我们得知,余数为几,1号就是该周的第几天,余0时为第7天。

d、获取用户输入月首次休息日为几号

我们知道1号为周几,该月有多少天之后,已经可以打印该月完整的日历了,下一步要思考的是,这些日期中哪些是上三休一的休息日。

首先想到日期差对4取余,但是总不能随着循环递增,一个月30天每天都取时间戳后与2月2号做差取余,这样效率太低。

我们只要知道输入月的第一个休息日是几号,后面的休息日都是四天一循环的规律,所以我们考虑先计算输入月的首个休息日为几号,之后循环判断打印即可。

e、循环打印日历

知道1号为周几后,先在1号前打印对应数量的空格或制表符。

需要定义一个指针变量来判断是否打印到了周六,到周六时需要换行打印。

然后打印首次休息日之前几天的日历。

接着加入是否为休息日的判断,继续循环打印整个月的日历。

四、任务拆解与代码

1、创建属性(用户输入的年和月,以及两个日历对象)

int inputYear;
int inputMonth;
Calendar calendarFirstRestDay = Calendar.getInstance();
Calendar calendarInput = Calendar.getInstance();

2、获取用户键盘输入的日期

创建getDate()方法,调用getYear()和getMonth()方法获取输入,并将输入的值赋值给对象

public void getDate() {
   
    System.out.println("提示:输入的年月须晚于2020年1月");
    getYear();
    getMonth();

    calendarFirstRestDay.set(Calendar.YEAR, 2020);
    calendarFirstRestDay.set(Calendar.MONTH, 1);

    calendarInput.set(Calendar.YEAR, inputYear);
    calendarInput.set(Calendar.MONTH, inputMonth -1);
}

编写getYear()和getMonth()方法,提示用户按需求输入日期

public void getYear() {
   
    Scanner input = new Scanner(System.in);
    System.out.println("请输入年份:");
    try {
   
        inputYear = input.nextInt();
        if (inputYear < 2020) {
   
            System.out.println("输入的年月须晚于2020年1月");
            getYear();
        }
    } catch (InputMismatchException e) {
   
        System.out.println("输入的年份有误");
        getYear();
    }
}

public void getMonth() {
   
    Scanner input = new Scanner(System.in
  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值