今天做了一道练习题,题目是要做个万年历,输入年份和月份,输出当月的日历。(已知1900年1月1日是星期一)
看完题目,我有个简单直接的思路:
首先算出来当月1号是星期几,从而确定了1号在日历中的位置,后面日期只要按顺序排列就好了。
所以重点应该是:如何计算出来当月1号是星期几。
为了计算这个,就要知道输入日期和参考日期(1900年1月1日)之间间隔了多少天。这其中涉及闰年的判断。
于是按照这个思路,我先初步写了一个,调试了几次后可以正确输出结果。
这段代码里只有main方法,全部融在一起,比较乱。
import java.util.Scanner;
public class practice{
public static void main(String[] args){
//输入年份和月份
Scanner sc = new Scanner(System.in);
System.out.print("请输入年份:");
int year = sc.nextInt();
System.out.print("请输入月份:");
int month = sc.nextInt();
//判断是否是闰年
//计算1990年1月1日至当前年份1月1日的日期差
int day = 0;
int flag = 2;
for(int i=1990;i<=year;i++){
if(i%4==0 && i%100!=0 || i%400 ==0){
if(i==year){
flag = 1;//表示当年是闰年
}else{
day = day + 366;
}
}else{
if(i==year){
flag = 0;//表示当年不是闰年
}else{
day = day + 365;
}
}
}
//加上当年1月1日至当月1号的日期差
switch(month){
case 12://只计算到当月12月1号
day = day + 30;//加上11月的30天
case 11:
day = day + 31;
case 10:
day = day + 30;
case 9:
day = day + 31;
case 8:
day = day + 31;
case 7:
day = day + 30;
case 6:
day = day + 31;
case 5:
day = day + 30;
case 4:
day = day + 31;
case 3:
if(flag==1){
day = day + 29;
}else if(flag==0){
day = day + 28;
}
case 2:
day = day + 31;
case 1:
break;
}
//根据日期差计算当月1号是周几
int weekNo = day%7+1;
//System.out.println("当月1号是weekNo:"+weekNo);
//计算当月总共多少天
int monthTotalDays = 0;
switch(month){
case 1:
monthTotalDays = 31;
break;
case 2:
if(flag==1){
monthTotalDays = 29;
}else if(flag==0){
monthTotalDays = 28;
}
break;
case 3:
monthTotalDays = 31;
break;
case 4:
monthTotalDays = 30;
break;
case 5:
monthTotalDays = 31;
break;
case 6:
monthTotalDays = 30;
break;
case 7:
monthTotalDays = 31;
break;
case 8:
monthTotalDays = 31;
break;
case 9:
monthTotalDays = 30;
break;
case 10:
monthTotalDays = 31;
break;
case 11:
monthTotalDays = 30;
break;
case 12:
monthTotalDays = 31;
break;
}
//打印日历抬头格式
System.out.println();
System.out.println(year+"年"+month+"月日历:");
System.out.println("日\t一\t二\t三\t四\t五\t六");
//找到当月1号的位置
for(int j=1;j<=weekNo;j++){
if(weekNo==7){
break;
}
System.out.print(" \t");
}
//辅助变量location,表示打印的位置,用于控制打印时换行
int location = 0;
if(weekNo!=7){
location = weekNo;
}
//开始打印日历
for(int i=1;i<=monthTotalDays;i++){
System.out.print(i+"\t");
if(location==6){
System.out.println();
location = 0;
}else{
location++;
}
}
}
}
自评一下:
1、粗心看错了题目,把1900年1月1日当成了1990年1月1日。巧合的是,这两个日子都是星期一,所以实际输出结果一样。
2、只能适用于输入日期晚于参考日期(1990年1月1日)的情况。
3、对于输入参数没有做校验。
4、格式比较乱。
于是整理了一下代码,在类中另外封装了三个方法,分别用来:
1、判断是否是闰年
2、计算当月1号是星期几
3、计算当月总天数
代码如下:
import java.util.Scanner;
public class Calandar{
//判断是否是闰年,是闰年返回true,否则返回false
public static boolean checkYear(int currentYear){
if(currentYear%4==0 && currentYear%100!=0 || currentYear%400 ==0){
return true;
}else{
return false;
}
}
//计算当月1号是星期几并返回
public static int firstDay(int currentYear,int month){
int day = 0;//日期差,当月1号和1990年1月1号之间相差的天数
int week = 0;//记录当月1号是星期几
if(currentYear>=1900){
for(int i=1900;i<currentYear;i++){
if(checkYear(i)){
day = day + 366;
}else{
day = day + 365;
}
}
//加上当年1月1日至当月1号的日期差
switch(month){
case 12://只计算到当月12月1号
day = day + 30;//加上11月的30天
case 11:
day = day + 31;
case 10:
day = day + 30;
case 9:
day = day + 31;
case 8:
day = day + 31;
case 7:
day = day + 30;
case 6:
day = day + 31;
case 5:
day = day + 30;
case 4:
day = day + 31;
case 3:
if(checkYear(currentYear)){
day = day + 29;
}else{
day = day + 28;
}
case 2:
day = day + 31;
case 1:
break;
}
//根据日期差计算当月1号是周几
week = day%7+1;
}else if(currentYear<1900 && currentYear>0){
for(int i=1899;i>currentYear;i--){
if(checkYear(i)){
day = day + 366;
}else{
day = day + 365;
}
}
//加上当月1号至当年12月31日的日期差
switch(month){
case 1://以当月1号计算
day = day + 31;//加上1月的31天
case 2:
if(checkYear(currentYear)){
day = day + 29;
}else{
day = day + 28;
}
case 3:
day = day + 31;
case 4:
day = day + 30;
case 5:
day = day + 31;
case 6:
day = day + 30;
case 7:
day = day + 31;
case 8:
day = day + 31;
case 9:
day = day + 30;
case 10:
day = day + 31;
case 11:
day = day + 30;
case 12:
day = day + 31;
break;
}
//根据日期差计算当月1号是周几
if(day%7==0){
week = 1;
}else{
week = 8-(day%7);
}
}
return week;
}
//计算当月总共多少天并返回
public static int totalDays(int currentYear,int month){
int monthTotalDays = 0;
switch(month){
case 1:
monthTotalDays = 31;
break;
case 2:
if(checkYear(currentYear)){
monthTotalDays = 29;
}else{
monthTotalDays = 28;
}
break;
case 3:
monthTotalDays = 31;
break;
case 4:
monthTotalDays = 30;
break;
case 5:
monthTotalDays = 31;
break;
case 6:
monthTotalDays = 30;
break;
case 7:
monthTotalDays = 31;
break;
case 8:
monthTotalDays = 31;
break;
case 9:
monthTotalDays = 30;
break;
case 10:
monthTotalDays = 31;
break;
case 11:
monthTotalDays = 30;
break;
case 12:
monthTotalDays = 31;
break;
}
return monthTotalDays;
}
public static void main(String[] args){
//输入年份和月份
Scanner sc = new Scanner(System.in);
System.out.print("请输入年份:");
int year = sc.nextInt();
if(year<=0){
System.out.println("年份输入错误");
return;
}
System.out.print("请输入月份:");
int month = sc.nextInt();
if(month<=0 || month >=13){
System.out.println("月份输入错误");
return;
}
//计算当月1号是周几
int weekNo = firstDay(year,month);
//计算当月总共多少天
int monthTotalDays = totalDays(year,month);
//打印日历抬头格式
System.out.println();
System.out.println(year+"年"+month+"月日历:");
System.out.println("日\t一\t二\t三\t四\t五\t六");
//找到当月1号的位置
for(int j=1;j<=weekNo;j++){
if(weekNo==7){
break;
}
System.out.print(" \t");
}
//辅助变量location,表示打印的位置,用于控制打印时换行
int location = 0;
if(weekNo!=7){
location = weekNo;
}
//开始打印日历内容
for(int i=1;i<=monthTotalDays;i++){
System.out.print(i+"\t");
if(location==6){
System.out.println();
location = 0;
}else{
location++;
}
}
}
}
20191019 更新:
利用java类库中的方法,实现输出当月日历。参考《Java核心技术卷(1)》P101
import java.time.*;
/**
输出当月日历
*/
public class CalendarTest{
public static void main(String[] args){
LocalDate date = LocalDate.now();
int month = date.getMonthValue();
int today = date.getDayOfMonth();
date = date.minusDays(today - 1);//Set to start of month
DayOfWeek weekday = date.getDayOfWeek();
int value = weekday.getValue();// 1 = Monday, ... 7 = Sunday
System.out.println("Mon\tTue\tWed\tThu\tFri\tSat\tSun");
for (int i = 1; i < value; i++)
System.out.print("\t");
while (date.getMonthValue() == month){
System.out.printf("%3d", date.getDayOfMonth());
if (date.getDayOfMonth() == today)
System.out.print("*\t");
else
System.out.print("\t");
date = date.plusDays(1);
if (date.getDayOfWeek().getValue() == 1) System.out.println();
}
if (date.getDayOfWeek().getValue() != 1) System.out.println();
}
}
20191029 更新
package com.zhuyifan.practiceDay11HomeWork;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class Test02 {
public static void main(String[] args) {
/**
* 设计一个方法,实现计算任意一年的任意一个月份有几天?
*/
System.out.println(getDays(1993, 2));
}
public static int getDays(int xyear, int xmonth) {
SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy年MM");
String year = String.valueOf(xyear);
String mouth = String.valueOf(xmonth);
Calendar rightNow = Calendar.getInstance();
try {
rightNow.setTime(simpleDate.parse(year + "年" + mouth));
} catch (ParseException e) {
e.printStackTrace();
}
int days = rightNow.getActualMaximum(Calendar.DAY_OF_MONTH);
return days;
}
}