零基礎學Java(10)物件導向-使用LocalDate類完成日曆設計

2022-07-25 12:03:00

前言

在我們完成這個日曆設計前,需要了解Java中的預定義類LocalDate的一些用法
 

語法

LocalDate.now() // 2022-07-01

會構造一個新物件,表示構造這個物件時的日期。
 

LocalDate.of(1999, 1, 1)

可以提供年、月和日來構造對應一個特定日期的物件:
 

當然,通常我們都希望將構造的物件儲存在一個物件變數中:

LocalDate newYearsEve = LocalDate.of(1999, 1, 1);

當有了一個LocalDate物件,可以用方法getYeargetMonthValuegetDayOfMonth得到年、月和日:

int year = newYearsEve.getYear(); // 1999
int month = newYearsEve.getMonthValue(); // 1
int day = newYeaersEve.getDayOfMonth(); // 1

上面的方法看起來沒什麼意義,因為這正是構造物件時使用的那些值。不過,有時可能有一個計算得到的日期,然後你希望呼叫這些方法來了解它的更多資訊。例如,plusDays方法會得到一個新的LocalDate,如果把應用這個方法的物件稱為當前物件,這個新日期物件則是距當前物件指定天數的一個新日期:

LocalDate aThousandDaysLater = newYearsEve.plusDays(1000);
year = aThousandDaysLater.getYear();  // 2002
month = aThousandDaysLater.getMonthValue();  // 09
day = aThousandDaysLater.getDayOfMonth();  // 26

aThousandDaysLater是在原來的日期上加了1000天,這時使用上面的方法就有效了
 

日曆實戰

需求:使用LocalDate類展示當前月的日曆,格式如下:

Mon Tue Wed Thu Fri Sat Sun
                  1*  2   3 
  4   5   6   7   8   9  10 
 11  12  13  14  15  16  17 
 18  19  20  21  22  23  24 
 25  26  27  28  29  30  31 

當前日期使用*號標記。可以看到,這個程式需要知道如何計算某月份的天數以及一個給定日期相應是星期幾。
 

步驟分解

①先構造一個物件,並用當前的日期初始化

`LocalDate date = LocalDate.now();`

②獲取當前的月份和日期

int month = date.getMonthValue();
int today = date.getDayOfMonth();

③將date設定為這個月的第一天,並得到這一天為星期幾

date = date.minusDays(today - 1);  // 設定為當月的第一天
DayOfWeek weekday = date.getDayOfWeek();
int value = weekday.getValue();  // 1 = Monday    7 = Sunday

變數weekday設定為DayOfWeek型別的物件。我們呼叫這個物件的getValue方法來得到星期幾的一個數值。我們會得到一個整數。星期一就返回1,星期二就返回2,依次類推,星期日就返回7.
④由於日曆的第一行是縮排的,這樣可使月份的第一天指向相應的星期幾。下面程式碼會列印表頭和第一行的縮排

System.out.println("Mon Tue Wed Thu Fri Sat Sun");
for (int i = 1; i < value; i++)
    System.out.print("    ");

⑤列印日曆的主體,進入一個迴圈,其中date遍歷一個月中的每一天。
每次迭代時,列印日期值。如果date是當前日期,這個日期則用一個*標記。接下來,把date推進到下一天。如果到達新的一週的第一天,則換行列印:

while (date.getMonthValue() == month) {
    System.out.printf("%3d", date.getDayOfMonth());
    if (date.getDayOfMonth() == today)
        System.out.print("*");
    else
        System.out.print(" ");
    date = date.plusDays(1);
    if (date.getDayOfWeek().getValue() == 1)
        System.out.println();
}

⑥什麼時候結束呢?我們不知道這個月有幾天,是28、29、30還是31。實際上,只要date還在當月就要繼續迭代
 

完整程式碼

import java.time.DayOfWeek;
import java.time.LocalDate;

/**
 * @author JKC
 * @Description:
 * @date 2022/7/1 10:53
 */
public class 製作日曆 {
    public static void main(String[] args) {
        // 建立一個日期物件,並進行初始化
        LocalDate date = LocalDate.now();
        System.out.println(date);
        // 獲取當前月份和日期
        int month = date.getMonthValue();
        int today = date.getDayOfMonth();

        // 將date設定為這個月的第一天,並得到這一天為星期幾
        date = date.minusDays(today - 1);
        // 設定為DayOfWeek型別的物件。呼叫這個物件的getValue方法來得到星期幾的一個數值
        DayOfWeek weekday = date.getDayOfWeek();
        int value = weekday.getValue();  // 1 = Monday    7 = Sunday

        System.out.println("Mon Tue Wed Thu Fri Sat Sun");
        for (int i = 1; i < value; i++)
            System.out.print("    ");

        while (date.getMonthValue() == month) {
            System.out.printf("%3d", date.getDayOfMonth());
            if (date.getDayOfMonth() == today)
                System.out.print("*");
            else
                System.out.print(" ");
            date = date.plusDays(1);
            if (date.getDayOfWeek().getValue() == 1)
                System.out.println();
        }
        if (date.getDayOfWeek().getValue() != 1)
            System.out.println();
    }
}

 

結論

上面的範例程式的重點是展示如何使用一個類的介面完成相當複雜的任務,而無須瞭解實現細節
 

LocalDate API

static LocalDate now()
構造一個表示當前日期的物件

static LocalDate of(int year, int month, int day)
構造一個表示給定日期的物件

int getYear()
int getMonthValue()
int getDayOfMonth()
得到當前日期的年、月和日。

DayOfWeek getDayOfWeek
得到當前日期是星期幾,作為DayOfWeek類的一個範例返回。呼叫getValue來得到1~7之間的一個數,表示這是星期幾,1表示星期一,7表示星期日

LocalDate plusDays(int n)
LocalDate minusDays(int n)
生成當前日期之後或之前n天的日期