首頁(yè)技術(shù)文章正文

Java培訓(xùn):控制臺(tái)打印日歷

更新時(shí)間:2022-09-15 來(lái)源:黑馬程序員 瀏覽量:

  朋友們大家好,今天我給大家?guī)?lái)一個(gè)控制臺(tái)小程序——打印當(dāng)月的日歷,效果如下圖:

1663210372068_01.jpg

   筆者運(yùn)行這個(gè)程序的時(shí)候是2022年7月30日,所以在日期的30后面加了一個(gè)*符號(hào)。

   這個(gè)程序很簡(jiǎn)單,但有些知識(shí)點(diǎn)我也會(huì)為大家詳細(xì)介紹,接下來(lái)按這個(gè)順序來(lái)為大家講解:

  1. java.util.Calendar類的使用

  
      2. 控制臺(tái)布局的設(shè)計(jì)

  
      3. 程序分步實(shí)現(xiàn)

  
      4. 完整代碼清單

  
      5. 結(jié)束語(yǔ)

  一. java.util.Calendar類的使用

   在Java類庫(kù)中有一個(gè)類:java.util.Calendar類,它是一個(gè)“抽象類”,它里面定義了一些方法,可以進(jìn)行日期的運(yùn)算,從而我們可以計(jì)算出某年某月的日歷。

  1.1 獲取對(duì)象

   通過(guò)API文檔我們可以發(fā)現(xiàn),Calendar類是一個(gè)“抽象類”,不能直接new對(duì)象,我們可以使用它的子類:java.util.GregorianCalendar,例如:

Calendar cal = new GregorianCalendar();

  這種方式可以獲取封裝了當(dāng)前系統(tǒng)日期和時(shí)間的GregorianCalendar對(duì)象。當(dāng)然,它還有其它構(gòu)造方法,全部構(gòu)造方法如下圖:

1663210403579_02.jpg

  1.2 獲取字段

   在Calendar類中提供了一個(gè)get(int field)方法,可以獲取某個(gè)字段的值,例如,下例我們獲取這個(gè)GregorianCalendar對(duì)象的:年、月、日、小時(shí)、分、秒、星期等信息:

public class CalendarDemo01 {
    public static void main(String[] args) {
        //1.獲取Calendar的子類對(duì)象
        Calendar gc = new GregorianCalendar();
        System.out.println(gc);
        //2.成員方法:public int get(int field):獲取某個(gè)字段的值
        int year = gc.get(Calendar.YEAR);
        int month = gc.get(Calendar.MONTH) + 1;
        int day = gc.get(Calendar.DAY_OF_MONTH);
//        int hour = gc.get(Calendar.HOUR);//12小時(shí)
        int hour = gc.get(Calendar.HOUR_OF_DAY);//24小時(shí)
        int minute = gc.get(Calendar.MINUTE);
        int second = gc.get(Calendar.SECOND);
        int week = gc.get(Calendar.DAY_OF_WEEK);//返回值:1--7,表示:星期日,星期一,星期二,...,星期六
        System.out.println(year + "年" + month + "月" + day + "日 " + hour + ":" + minute + ":" + second);
        System.out.println(getWeek(week));
    }

    //定義一個(gè)方法,接收一個(gè)int的值,返回:星期日,星期一,星期二,...,星期六
    public static String getWeek(int w) {//1,2,3,4,5,6,7
        //查表法
        String[] weeks = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        //         索引:    [0]      [1]      [2]      [3]      [4]      [5]      [6]
        return weeks[w - 1];
    }
}

  1.3 設(shè)置字段

   如果我們已有一個(gè)表示當(dāng)前系統(tǒng)日期和時(shí)間的GregorianCalendar對(duì)象,想計(jì)算1949年10月01日那天是星期幾,我們可以對(duì)這個(gè)GregorianCalendar對(duì)象的年、月、日重新設(shè)置。

   Calendar類中提供了一個(gè)set(int field,int value)方法,可以設(shè)置某個(gè)字段的值。設(shè)置后,當(dāng)前對(duì)象的其它相關(guān)字段都會(huì)被設(shè)置到新設(shè)置的日期上,比如:設(shè)置了新的日期,"星期"字段會(huì)自動(dòng)更改為新日期的星期值,示例代碼如下:

public class CalendarDemo02 {
    public static void main(String[] args) {
        //1.獲取Calendar的子類對(duì)象
        Calendar gc = new GregorianCalendar();
        System.out.println(gc);

        //2.成員方法:public void set(int field,int value):設(shè)置字段的值
        //將gc對(duì)象設(shè)置為:1949年10月01日
        gc.set(Calendar.YEAR, 1949);
        gc.set(Calendar.MONTH, 10- 1);
        gc.set(Calendar.DAY_OF_MONTH, 1);

        //3.獲取周幾
        int w = gc.get(Calendar.DAY_OF_WEEK);
        String week1 = getWeek(w);
        System.out.println("1949年10月01日那天是:" + week1);
    }

    //定義一個(gè)方法,接收一個(gè)int的值,返回:星期日,星期一,星期二,...,星期六
    public static String getWeek(int w) {//1,2,3,4,5,6,7
        //查表法
        String[] weeks = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        //         索引:    [0]      [1]      [2]      [3]      [4]      [5]      [6]
        return weeks[w - 1];
    }
}

  1.4 為某個(gè)字段增加/減少指定的值

   如果我們已有一個(gè)表示當(dāng)前系統(tǒng)日期和時(shí)間的GregorianCalendar對(duì)象,想計(jì)算200天后的年、月、日、星期幾,我們可以使用add(int field,int value)方法,示例代碼如下:

public class CalendarDemo03 {
    public static void main(String[] args) {
        //1.獲取Calendar的子類對(duì)象
        Calendar gc = new GregorianCalendar();
        System.out.println(gc);

        //2.成員方法:public void add(int field,int value):增加/減少指定字段的值
        //將日期增加200
        gc.add(Calendar.DAY_OF_MONTH, 200);
        //3).獲取年、月、日,星期
        int year = gc.get(Calendar.YEAR);
        int month = gc.get(Calendar.MONTH) + 1;
        int day = gc.get(Calendar.DAY_OF_MONTH);
        int w = gc.get(Calendar.DAY_OF_WEEK);
        System.out.println("200天后是:" + year + "年" + month + "月" + day + "日 " + getWeek(w));
    }

    //定義一個(gè)方法,接收一個(gè)int的值,返回:星期日,星期一,星期二,...,星期六
    public static String getWeek(int w) {//1,2,3,4,5,6,7
        //查表法
        String[] weeks = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        //         索引:    [0]      [1]      [2]      [3]      [4]      [5]      [6]
        return weeks[w - 1];
    }
}

  Calendar和子類GregorianCalendar中還有很多其它方法,大家可以參考API文檔。

  二. 控制臺(tái)布局設(shè)計(jì)

   在控制臺(tái)上,如果想將多行的每列數(shù)據(jù)對(duì)齊,我們需要進(jìn)行一些設(shè)計(jì),主要是結(jié)合"空格"和"制表符"使多行中的多列數(shù)據(jù)實(shí)現(xiàn)對(duì)齊的效果。本例的設(shè)計(jì)思路如下圖:

1663210422566_03.jpg

  說(shuō)明:

  1. 每列之間用一個(gè)制表符分隔;

  
       2. 每列的單元格內(nèi)部使用兩個(gè)字符位。

  
       三. 程序分步實(shí)現(xiàn)

   根據(jù)上面的設(shè)計(jì)思路,我們就可以進(jìn)行分步驟的編寫(xiě)代碼了。

  3.1 打印頭部

   我們?cè)O(shè)計(jì)一個(gè)類CalendarShow,內(nèi)部包含一個(gè)成員屬性:GregorianCalendar對(duì)象,并且在構(gòu)造方法時(shí)為其初始化為當(dāng)前日期:

public class CalendarShow {
    private Calendar cal;
    public CalendarShow() {
        cal = new GregorianCalendar();
    }
    public String toString() {
        StringBuilder sb = new StringBuilder(top() + "\n");//把top添加進(jìn)來(lái)并換行
        return sb.toString();
    }

    private String top() {
        int year = cal.get(Calendar.YEAR);//獲取年
        int month = cal.get(Calendar.MONTH) + 1;//獲取月
        String yearOrMonth = year + "年" + month + "月";//年月字符串
        String weekTop = "日\(chéng)t一\t二\t三\t四\t五\t六";//日歷頭
        return yearOrMonth + "\n" + weekTop;
    }

    public static void main(String[] args) {
        CalendarShow cs = new CalendarShow();
        System.out.println(cs);
    }
}

  運(yùn)行后,效果如下:

1663210435405_04.jpg

  3.2 打印日期

   接下來(lái)我們填充下面的日期部分。

  - 首先,我們先計(jì)算本月1日是星期幾:

  int today = cal.get(Calendar.DAY_OF_MONTH);//獲取當(dāng)前是幾號(hào)
  cal.set(Calendar.DAY_OF_MONTH, 1);//設(shè)置為本月一號(hào)
  int weekOfOne = cal.get(Calendar.DAY_OF_WEEK);//獲取一號(hào)是周幾

  由于我們要在"今天"的日期右側(cè)添加一個(gè)*符號(hào),所以,在設(shè)置日期前,將當(dāng)前日期先取出。

  - 獲取星期后,假如是星期五,那么為了在五的下面輸出1,我們先在前面的:日、一、二、三、四的每列上添加兩個(gè)空格和一個(gè)制表符:

for(int i = Calendar.SUNDAY; i < weekOfOne; i++) {//在一號(hào)前添加前置空格,使一號(hào)顯示在對(duì)應(yīng)的星期頭下方
              sb.append("   \t");
  }

  - 輸出日期:

int month = cal.get(Calendar.MONTH);//獲取當(dāng)前是幾月
  while(month == cal.get(Calendar.MONTH)) {//循環(huán)中會(huì)對(duì)日期不斷增加,當(dāng)增加到下個(gè)月時(shí)就跳出循環(huán)
      int day = cal.get(Calendar.DAY_OF_MONTH);//獲取當(dāng)前日期
      if(day < 10) {//如果日期小于10,在前面加前導(dǎo)空格(填充補(bǔ)位的作用)
          sb.append(" " + day);
      } else {
          sb.append(day);//如果日期大于等于10,說(shuō)明是兩位數(shù)的日期,無(wú)需添加空格
      }
      if(day == today) {//如果日期是當(dāng)天,在后面添加星號(hào)和空格,表示當(dāng)天的意思
          sb.append("* ");
      } else {
          sb.append("\t");//如果日期不是當(dāng)天,在后面添加一個(gè)制表符
      }
      int week = cal.get(Calendar.DAY_OF_WEEK);//獲取當(dāng)前是星期幾
      if(week == Calendar.SATURDAY) {//如果是星期六換行
          sb.append("\n");
      }
      cal.add(Calendar.DAY_OF_MONTH, 1);//把日期加1
  }
  return sb.toString();

  四. 完整代碼清單

package com.heima.se;

import java.util.Calendar;
import java.util.GregorianCalendar;

/**
 * 在控制臺(tái)打印日歷:要求使用的控制臺(tái)字體必須一個(gè)漢字的寬度對(duì)應(yīng)兩個(gè)字符的寬度。
 *
 */
public class CalendarShow {
    private Calendar cal;
    public CalendarShow() {
        cal = new GregorianCalendar();
    }
    public String toString() {
        StringBuilder sb = new StringBuilder(top() + "\n");//把top添加進(jìn)來(lái)并換行
        int today = cal.get(Calendar.DAY_OF_MONTH);//獲取當(dāng)前是幾號(hào)
        cal.set(Calendar.DAY_OF_MONTH, 1);//設(shè)置為本月一號(hào)

        int weekOfOne = cal.get(Calendar.DAY_OF_WEEK);//獲取一號(hào)是周幾
        for(int i = Calendar.SUNDAY; i < weekOfOne; i++) {//在一號(hào)前添加前置空格,使一號(hào)顯示在對(duì)應(yīng)的星期頭下方
            sb.append("   \t");
        }

        int month = cal.get(Calendar.MONTH);//獲取當(dāng)前是幾月
        while(month == cal.get(Calendar.MONTH)) {//循環(huán)中會(huì)對(duì)日期不斷增加,當(dāng)增加到下個(gè)月時(shí)就跳出循環(huán)
            int day = cal.get(Calendar.DAY_OF_MONTH);//獲取當(dāng)前日期
            if(day < 10) {//如果日期小于10,在前面加前導(dǎo)空格(填充補(bǔ)位的作用)
                sb.append(" " + day);
            } else {
                sb.append(day);//如果日期大于等于10,說(shuō)明是兩位數(shù)的日期,無(wú)需添加空格
            }
            if(day == today) {//如果日期是當(dāng)天,在后面添加星號(hào)和空格,表示當(dāng)天的意思
                sb.append("* ");
            } else {
                sb.append("\t");//如果日期不是當(dāng)天,在后面添加制表符
            }
            int week = cal.get(Calendar.DAY_OF_WEEK);//獲取當(dāng)前是星期幾
            if(week == Calendar.SATURDAY) {//如果是星期六換行
                sb.append("\n");
            }
            cal.add(Calendar.DAY_OF_MONTH, 1);//把日期加1
        }
        return sb.toString();
    }

    private String top() {
        int year = cal.get(Calendar.YEAR);//獲取年
        int month = cal.get(Calendar.MONTH) + 1;//獲取月
        String yearOrMonth = year + "年" + month + "月";//年月字符串
        String weekTop = "日\(chéng)t一\t二\t三\t四\t五\t六";//日歷頭
        return yearOrMonth + "\n" + weekTop;
    }

    public static void main(String[] args) {
        CalendarShow cs = new CalendarShow();
        System.out.println(cs);
    }
}

  五. 結(jié)束語(yǔ)

   在本文中,我們了解了Calendar及其子類GregorianCalendar的基本使用,以及對(duì)控制臺(tái)輸出內(nèi)容進(jìn)行對(duì)齊的一些小技巧,通過(guò)這些,我們就可以很美觀的打印某年某月的一個(gè)日歷,是不是很酷!后續(xù)的文章,我會(huì)為大家?guī)?lái)更多、更有趣、更實(shí)用的一些案例,請(qǐng)大家持續(xù)關(guān)注哦!

分享到:
在線咨詢 我要報(bào)名
和我們?cè)诰€交談!