在Console中输出类似Windows系统的日历

       记得之前蔡工说过一道题:在Java的控制台中打印用户指定月份的日历,要求类似Windows系统任务栏右侧的日历。一直觉着很简单没去做,今天有空,就拿来练练手磨磨刀,免得Java基础忘得一干二净吧。该工程有两个类,一个执行类(Run.java),一个自然月类(Month.java)。现将代码贴上,如下:

Run类

package com.printcalendar.run;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Run {
	Month inputMonth = null;
	boolean debug = false;//Just for debug when it's necessary.
	//获得用户输入,并简单判断输入合法性
	private boolean getUserInput() {
		int year;
		int month;
		String preYear = null;
		String preMonth = null;
		System.out.print("Input destination year:");
		preYear = new Scanner(System.in).next();
		System.out.print("Input destination month:");
		preMonth = new Scanner(System.in).next();
		if( isNumeric(preYear) ) {
			year = Integer.parseInt(preYear);
		} else {
			return false;
		}
		if( isNumeric(preMonth) ) {
			month = Integer.parseInt(preMonth);
		} else {
			return false;
		}
		if( !(year> 0 && year< 10000) ) {		
			return false;
		}
		if( !(month> 0 && month< 13) ) {		
			return false;
		}
		inputMonth = new Month(year, month);
		return true;
	}
	//检查指定字串内容是否为数字
	private boolean isNumeric(String str) {
		Matcher isNum = Pattern.compile("[0-9]*").matcher(str);
		if( !isNum.matches() ) {
			return false;
		} else {
			return true;
		}
	}
	//检查指定年份是否为闰年:四年一闰,百年不闰,四百年再闰
	private boolean isLeapYear(int year) {
		if ( (year% 4== 0 && year%100!= 0) || year% 400== 0 ) {
			return true;
		} else {
			return false;
		}
	}
	//获取两个自然月实例之间的自然日差值(以2016年1月为基准)
	private int getBetweenDays(Month month) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		long day1= 0,day2= 0;
		try {
			day1 = sdf.parse("2016-1-1").getTime();
			day2 = sdf.parse(month.getYear()+ "-"+ month.getMonth()+ "-1").getTime();
		} catch (ParseException e) {
			e.printStackTrace();
		}
		long betweenDays = Math.abs(day1- day2)/86400000;//86400000=1000*60*60*24
		return (int)betweenDays;
	}
	//设置指定月的天数
	private void setMonthLength(Month month) {
		switch(month.getMonth()) {
		case 2:
			if( isLeapYear(month.getYear()) ) {
				month.setmonthLength(29);
			} else {
				month.setmonthLength(28);
			}
			break;
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12:
			month.setmonthLength(31);
			break;
		default:
			month.setmonthLength(30);
			break;
		}
	}
	//设置指定自然月实例第一天(1号)为星期几:Sunday=1,Monday=2,...,Saturday=7
	private void setOrdinalDay(Month month) {//Sun=1,Sat=7
		int result = getBetweenDays(month)% 7;
		//↓ ↓ ↓ D E B U G ↓ ↓ ↓
		if(debug == true) {
			System.out.println("[DEBUG]"+ "BetweenDays="+ getBetweenDays(month));
			System.out.println("[DEBUG]"+ "result="+ result);
		}
		//↑ ↑ ↑ D E B U G ↑ ↑ ↑
		if(month.getYear()>= 2016) {//When the "month" after 2016.01
			switch(result) {
				case 0:
					month.setOrdinalDay(6);
					break;
				case 1:
					month.setOrdinalDay(7);
					break;
				case 2:
					month.setOrdinalDay(1);
					break;
				case 3:
					month.setOrdinalDay(2);
					break;
				case 4:
					month.setOrdinalDay(3);
					break;
				case 5:
					month.setOrdinalDay(4);
					break;
				case 6:
					month.setOrdinalDay(5);
					break;
				default:
			}
		} else {//When the "month" before 2016.01
			switch(result) {
				case 0:
					month.setOrdinalDay(6);
					break;
				case 1:
					month.setOrdinalDay(5);
					break;
				case 2:
					month.setOrdinalDay(4);
					break;
				case 3:
					month.setOrdinalDay(3);
					break;
				case 4:
					month.setOrdinalDay(2);
					break;
				case 5:
					month.setOrdinalDay(1);
					break;
				case 6:
					month.setOrdinalDay(7);
					break;
				default:
			}
		}
	}
	//按照Windows系统任务栏的日历格式在控制台输出
	private void layout(Month month) {
		System.out.println();
		System.out.println("    ===   "+ month.getYear()+ "-"+ month.getMonth()+ "   ===");
		System.out.println();
		System.out.println("Sun Mon Tue Wed Thu Fri Sat");
		int od = month.getOrdinalDay();
		//↓ ↓ ↓ D E B U G ↓ ↓ ↓
		if(debug == true) {
			System.out.println("[DEBUG]"+ "OrdinalDay="+ od);
		}
		//↑ ↑ ↑ D E B U G ↑ ↑ ↑
		for(int i= 0; i< (od- 1)* 4; i++) {
			System.out.print(" ");
		}
		int counter = 0;
		for(int i= 1; counter< month.getmonthLength(); i++) {
			if( (od+ counter- 1)% 7== 0 ) {
				System.out.println();
			}
			System.out.printf("%2d",i);
			System.out.print("  ");
			counter++;
		}
	}
	
	//Constructor
	public Run() {
		if( !getUserInput() ) {
			System.out.println("sth. wrong");			
		}
		setMonthLength(inputMonth);
		setOrdinalDay(inputMonth);
		layout(inputMonth);
	}
	
	public static void main(String[] args) {
		new Run();
	}
}



 
Month类 

package com.printcalendar.run;

public class Month {
	private int year;//Which year is it.
	private int month;//The first of several be this month of the year
	private int ordinalDay;//The first of several be ((the first day of this month) of the week).
	private int monthLength;//How many days does the month has.
	
	public int getYear() {
		return year;
	}
	//@unused
	public void setYear(int year) {
		this.year = year;
	}
	public int getMonth() {
		return month;
	}
	//@unused
	public void setMonth(int month) {
		this.month = month;
	}
	public int getOrdinalDay() {
		return ordinalDay;
	}
	public void setOrdinalDay(int ordinalDay) {
		this.ordinalDay = ordinalDay;
	}
	public int getmonthLength() {
		return monthLength;
	}
	public void setmonthLength(int monthLength) {
		this.monthLength = monthLength;
	}
	
	//Constructor
	public Month(int year, int month) {
		this.year = year;
		this.month = month;
	}
}




由于是在单位的电脑上写的,而那儿的电脑又是全日文环境,编码是Shift-JIS,不能打汉字。所以写的时候基本是英文注释,现在上面的中文注释都是临时加的。因为加得比较匆忙,可能会有些不准确甚至错误,以后发现了再来修改吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值