不是技术贴,只是记录贴,,,
主函数:输入年、月,输出月份日历。
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
System.out.print("Enter full year: ");
int year = input.nextInt();
System.out.print("Enter month between 1 and 12: ");
int month = input.nextInt();
printMonth(year,month);
}
因为日历上面具体月、年是另外的算法,分开一个函数,中间虚线和星期是不变的,另外处理。日历又分为两部分,上面显示具体年月日,下面显示月份日期。类似下图:
先划分两个模块,一个作为标题,一个作为主题,如下:
public static void printMonth(int year,int month) {
//System.out.println(month + " " + year);
printMonthTitle(year,month);
printMonthBody(year,month);
}
先把简单的标题部分写好,一个月份名字,显示输入年份,以及分割线和星期,这里的空格和长度要对应好显示的日期,如下:
public static void printMonthTitle(int year,int month) {
System.out.println(" " + getMonthName(month) + " " + year);
System.out.println("----------------------------- " );
System.out.println(" Sun Mon Tue Wed Thu Fri Sat ");
}
年份直接获取输入数字即可,月份要转换一下,将输入的1-12转换成对应的英文显示。
public static String getMonthName(int month) {
String monthName = "";
switch (month) {
case 1: monthName = "January";break;
case 2: monthName = "February";break;
case 3: monthName = "March";break;
case 4: monthName = "April";break;
case 5: monthName = "May";break;
case 6: monthName = "June";break;
case 7: monthName = "July";break;
case 8: monthName = "August";break;
case 9: monthName = "September";break;
case 10: monthName = "October";break;
case 11: monthName = "November";break;
case 12: monthName = "December";
}
return monthName;
}
现在,标题部分就算是可以了,下面是具体日期内容,先是显示部分,注意一下注释说的问题,不然报错如下:
public static void printMonthBody(int year,int month) {
int startDay = getStartDay(year,month);
//System.out.println("startDay = " + startDay);
int numberOfDaysInMonth = getNumberOfDaysInMonths(year,month);
//System.out.println("numberOfDaysInMonth = " + numberOfDaysInMonth);
for (int i = 0;i < startDay;i++){
System.out.print(" "); //这里空格数是4,不对的话第一行位置会偏
}
for (int i = 1;i < numberOfDaysInMonth + 1;i++){
//i=0,则日期从0开始,numberOfDaysInMonth + 1不加1则少一天
System.out.printf("%4d",i);
if ((i + startDay) % 7 == 0){
System.out.println();
}
}
System.out.println();
}
这是错的现象:,日期从0号开始,8月应该有31号的,但是少一天,第一行位置对不齐。
日历必须知道本月第一天是周几,从1800年1月1号开始算,通过求余知道当前是周几。
public static int getStartDay(int year,int month) {
final int START_DAY_FOR_JAN_1_1800 = 4;//原 3 时间慢了一天
int totalNumberOfDay = getTotalNumberOfDays(year,month);
return (totalNumberOfDay + START_DAY_FOR_JAN_1_1800) % 7;
}
这里还得计算当前输入时间距离1800年1月1号多少天。
public static int getTotalNumberOfDays(int year,int month) {
int total = 0;
for (int i = 0;i < 1800;i++){
if(isLeapYear(i)) {
total = total + 366;
}
else {
total = total + 365;
}
}
for (int i = 0;i < month;i++) {
total = total + getNumberOfDaysInMonths(year,i);
}
return total;
}
月份有大小月,要分开处理大月小月,再统计总的天数。
public static int getNumberOfDaysInMonths(int year,int month) {
if ((month == 1) || (month == 3) || (month == 5) || (month == 7)
|| (month == 8) || (month == 10) || (month == 12)) {
return 31;
}
if ((month == 4) || (month == 6) || (month == 9) || (month == 11)){
return 30;
}
if (month == 2)
return isLeapYear(year) ? 29:28;
return 0;//如果月份错误
}
阳历还有闰年,也要计算,根据是否闰年计算天数
public static boolean isLeapYear(int year) {
// return true;
return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
}
这样,整个程序就写完了,效果如图: