题目 1493: [蓝桥杯][算法提高VIP]任意年月日历输出


题目描述

已知2007年1月1日为星期一。
设计一函数按照下述格式打印2007年以后(含)某年某月的日历,2007年以前的拒绝打印。
为完成此函数,设计必要的辅助函数可能也是必要的。其中输入为年分和月份。
注意:短线“-”个数要与题目中一致,否则系统会判为错误。
输入
年月和月份
输出

样例输入
2010 9
样例输出
在这里插入图片描述


解题思路

首先这道题涉及到了时日期类的使用,而我们了解的有Date类,Calendar类,以及LocalDateTime,但是在蓝桥杯中,有由于JDK要求为1.6版本,所以LocalDateTime没法用,但是感兴趣的阔以去了解一下。
因为在LocalDate中有一个。getDayOfWeek方法,可以直接获取这一天是星期几。
在这里插入图片描述
对于这道题,首先我们需要获得所打印月份的1号也就是这个月的第一天是星期几,然后一次往后打印。
这个呢,其实方法不少,就像上面那个getDayOfWeek方法,但是不能用。

在Calendar类中,有一个DAY_OF_WEEK的方法,可以得到每个月1号是星期几

在这里插入图片描述

至于Date类这个我没写,为什么呢–>(API上给你解释了)
在这里插入图片描述

还有一种方法,就是这道题它最开始给了一个2007-1-1这一天是星期一,那么我们能不能获取所需打印月份的第一天与2007-1-1的天数差,然后取余7得到的余数不就是所需打印月份1号的星期数

public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int y = sc.nextInt(); // 年
		int m = sc.nextInt(); // 月
		Calendar calendar1 = Calendar.getInstance();
		calendar1.set(2007, 0, 1); // 给定的2007-1-1
		Calendar calendar2 = Calendar.getInstance(); 
		calendar2.set(y, m - 1, 1); // 所需打印月份的1号
		long t1 = calendar1.getTimeInMillis(); // 获取时间戳
		long t2 = calendar2.getTimeInMillis();
		long days = (t2-t1)/(24*60*60*1000); // 天数差
		System.out.println(days%7+1);
	}

其次,我们需要知道所需打印月份有多少天,也就是说我们要获取边界。

	这个呢,在Calendar类中,有一个.getActualMaximum方法,它是用来获取指定字段的最大值。
	看上去感觉跟我们要求的月份有多少天没什么关联,
	这个指定字段如果我们用DATE的话,是不是就可以理解为天数的最大值
	即这个所求打印月份的天数不就得到了

在这里插入图片描述

最后呢,就是要打印日历了。我们看上面样例输出给的打印图,去找有什么限定格式没有。

1.对于前三行虚线和字母部分以及最后一行的虚线,直接cv上去,防止因为这个小问题出错。
2.它的每个数字都是在靠右,这个格式需要注意,一不小心就忘了

代码如下

import java.util.Calendar;
import java.util.Scanner;

/**
 * 任意年月日历输出
 * @author hf
 *
 */
public class Cyyw1493 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int y = sc.nextInt(); // 年
		int m = sc.nextInt(); // 月
		Calendar calendar = Calendar.getInstance(); 
		calendar.set(y, m - 1, 1); // 指定月份的1号

		// 获取这个月1号是星期几
		int x = calendar.get(Calendar.DAY_OF_WEEK) - 1;
		int count = 0; // 换行变量
		// 获取这个月的天数
		int d = calendar.getActualMaximum(Calendar.DATE);

		System.out.println("---------------------");
		System.out.println(" Su Mo Tu We Th Fr Sa");
		System.out.println("---------------------");
		// 打印1号之前的日历空格
		for (int i = 1; i <= x; i++) {
			System.out.print("   ");
			count++;
		}
		// 开始从1号开始打印,一直到整个月结束,每到星期天就换行,并且每个元素都是靠右
		for (int day = 1; day <= d; day++) {
			if (count == 7) {
				System.out.println();
				count = 0;
			}
			System.out.print(String.format("%3d", day));
			count++;
		}
		System.out.println();
		System.out.println("---------------------");
		
		sc.close();
	}
}

运行示例

这是写的当下月份打印的效果:
在这里插入图片描述
这是电脑上的日历:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值