简易万年历

今天做了一道练习题,题目是要做个万年历,输入年份和月份,输出当月的日历。(已知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;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容