碎碎念
不是吧,阿sir,996还不让人摸鱼,BOOS果断让人事部做出计划整改,改就改吧.为什么让我来写这个那,我自己制裁我自己可还行,看了看自己不争气的花呗!整啊,加油啊打工人.
背景
某公司软件开发工程师孙工,作息规律为上三天班,休息一天,经常不确定休
息日是否周末,为此,请你开发一个程序,当孙工输入年及月,以日历方式显示对
应月份的休息日,用中括号进行标记.同时,统计出本月有几天休息,轮到周末休
息有几天.(注:首次休息日是 2020 年 2 月 2 日)
产品经理
嘀嘀嘀嘀 , 产品经理将界面和需求一股脑发了过来.
产品界面:
需求概述:
- 获得输入数据:年,月
- 通过计算进行展示
- 同步输出统计信息
- 程序回到下一次的输入数据状态
大战开始
话不多说! 开撸开撸,刚开始撸,bug漫天飞,我摸摸了本来头发就不多的头皮,自己开撸.终于在下班前撸了出来.想了想mvc,还是算了吧,老老实实写写得了.
MVC的概念,将数据操作层,流程控制层和视图层尽可能分开,这样每个模块之间的关联尽可能地变小(低耦合),在编写大项目时可以使得程序整体逻辑清晰可见,易于维护和修改,体现出java的核心优势之一
需求分析(三步走战略)
第一,最明显的需要打印出一个日历来
第二,需要标记出孙工的休息日用[ ]标记出来
第三,需要算出来,孙工在他查询的那个月有几天的休息日,并且休息日有几天在周末
具体实现
接收用户输入的年份和月份
有人要问,为啥你接收个数据还要另外写个函数那?我说年轻人,年份和月份老讲究的,一不小心就有一些夸张的事情了.
- 年份:老张2020才营业,你写前面就不合适了吧,还有老张不会在公司干的寿终正寝吧!
- 月份:一年也就12个月,你在创造点可还行!
int year = -1 ;
int month = -1;
System.out.println("请输入年份:");
year = input(2020,2080);
System.out.println("请输入月份:");
month = input(1,12);
/**
* 1.接收数据 2.排除非法数据
* @param min
* @param max
* @return
*/
public static int input(int min,int max) {
String input = scanner.nextLine();
int number = -1;
try {
number = Integer.parseInt(input);
} catch (NumberFormatException e) {
System.out.println("输入有误,请重新输入!");
return input(min, max);
}
if (number < min || number > max) {
System.out.println("输入有误,请重新输入!");
return input(min,max);
}
return number;
}
Calendar类的使用
将获取到的数据进行处理:
- 月份: 这里有个细节,月份是从0开始的,就是0月对应的是1月,所以输入的值要减一.
- 获得每个月的一号是星期几
- 算算每个月的天数
- 打印一下表头和那个第一行的空格
- 空格数等于 = 一号对应星期数- 1
jdk11中常量的描述:
//创建日历类对象
Calendar calendar = Calendar.getInstance();
/**
* 设置年 月(0-11) 日
*/
calendar.set(Calendar.YEAR,year);
calendar.set(Calendar.MONTH,month-1);
calendar.set(Calendar.DATE,1);
//判断日历的初始值是星期几
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
//System.out.println(dayOfWeek);
//获取本月的最大天数
int daysMaxOfMonth = calendar.getActualMaximum(Calendar.DATE);
//System.out.println(daysMaxOfMonth);
//打印日历表头
System.out.println("星期日\t星期一\t星期二\t星期三\t星期四\t星期五\t星期六");
for(int i = 1;i <= dayOfWeek - 1; i++){
System.out.printf("%-8s","");
}
这个时候,我看了看关于几个变量的描述:
jdk11中关于使用getActualMaximum方法的描述
public int getActualMaximum(int field)
给定此Calendar的时间值,返回指定日历字段可能具有的Calendar 。 例如, MONTH字段的实际最大值在某些年份为12,在希伯来日历系统中为其他年份的13。
此方法的默认实现使用迭代算法来确定日历字段的实际最大值。 如果可能,子类应该使用更有效的实现来覆盖它。
计算(抠脚丫子功夫)
//本月休假天数
int relaxDays = 0;
//本月休假的周末天数
int relaxWeekends = 0;
for (int i = 1;i <= daysMaxOfMonth;i++) {
//设置日
calendar.set(Calendar.DATE, i);
//得到当地日期与初始日期:2020.2.2 差的天数
int intervalDays = intervalDays(calendar);
//判断该天是不是休息日
if (intervalDays % 4 == 0) {
System.out.printf("%-8s","["+i+"]");
relaxDays++;
if (calendar.get(Calendar.DAY_OF_WEEK) == 1 ||calendar.get(Calendar.DAY_OF_WEEK) == 7) {
relaxWeekends++;
}
} else {
System.out.printf("%-8s",i);
}
if(calendar.get(Calendar.DAY_OF_WEEK) == 7){
System.out.println();
}
}
System.out.println();
System.out.println("本月休息的天数:"+relaxDays+"天");
System.out.println("本月轮到周末休息的天数:"+relaxWeekends+"天");
}
计算距离初始日期(2020.02.02)的方法
public static int intervalDays(Calendar c) throws ParseException {
//创建date对象
Date date = c.getTime();
//得到格林威治时间
long to = date.getTime();
//创建日期格式,用于记录初始日期
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//将初始日期转化为Date对象
Date initialDate = format.parse("2020-02-02");
//得到初始日期格林威治时间
long from = initialDate.getTime();
//计算两个格林威治时间的差,得到两个日期的相隔天数
int intervalalDays = (int) ((to - from) / (24 * 60 * 60 * 1000));
//初始日期是第一个休息日,在此之前不算
if(to - from < 0){
return -1;
}
return intervalalDays;
}
客官看到这了就给个赞吧!!!(需要源码的,私我呦!)