Java类库中的LocalDate类

Date类的实例有一个状态,即特定的时间点

时间是用距离一个固定时间点的毫秒数(可正可负)表示的,这个时间点就是纪元,它是UTC时间1970年1月1日00:00:00。

UTC就是Coordinated Universal Time(国际协调时间),和GMT(Greenwich Mean Time,格林尼治时间)一样,都是科学标准时间。

但是Date类对于处理人类记录日期的日历信息并不是很有用,如"December 31, 1999"。这种特定的日期描述遵循了世界上大多数地区使用的Gregorian阳历。
但是同样的这个时间点采用中国或希伯来的阴历来描述就不一样了。

类库设计者决定将保存时间与给时间点命名分开。所以标准Java类库分别包含了两个类:一个是用来表示时间点的Date类;另一个是用大家熟悉的日历表示法表示日期的LocalDate类。

将时间度量与日历分开是一种很好的面向对象设计。所以,最好使用不同的类表示不同的概念。

  • 不要使用构造器来构造LocalDate类的对象。实际上,应该使用静态工厂方法,它会代表你调用构造器。

LocalDate.now()会构造一个新对象,表示构造这个对象时的日期。

LocalDate.of(1999, 12, 31)可以提供年、月、日来构造对应一个特定日期的对象。

LocalDate newYearsEve = LocalDate.of(1999, 12, 31);将构造的对象保存在一个对象变量中。

// 一旦有一个LocalDate对象,可以用方法getYear、getMonthValue和getDayOfMonth得到年、月、日
int year = newYearsEve.getYear(); // 1999
int month = newYearsEve.getMonthValue(); // 12
int day = newYearsEve.getDayOfMonth(); // 31

plusDays方法会得到一个新的LocalDate,如果把应用这个方法的对象称为当前对象,这个新日期对象就是距离当前对象指定天数的一个新日期
plusDays方法会生成一个新的LocalDate对象,然后把新对象赋给aThousandDaysLater变量。原来的对象不做任何改动。所以plusDays方法没有 更改 这个方法的对象。
只访问对象而不修改对象的方法被称为访问器方法。例如,LocalDate.getYear

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

LocalDate类封装了实例字段来维护所设置的日期。如果不查看源代码,就不知道类内部的日期表示。封装的意义就在于内部表示并不重要,重要的是类对外提供的方法。

Date类也有得到年、月、日的方法,分别是getDay、getMonth、getYear,不过这些方法已经废弃。(当类库设计者意识到某个方法最初就不该引入的时候,就把它标记为废弃,不鼓励使用。虽然程序中可以使用这些方法,但是不推荐使用,因为可能在未来的版本中完全删除它们)

JDK提供了jdeprscan工具来检查你代码中是否使用了Java API已经废弃的特性。


打印日历

package time;

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

public class CalendarTest {
    public static void main(String [] args){
        // 首先构造一个对象,并用当前的日期初始化
        LocalDate date = LocalDate.now();
        // 获得当前的月份和日期
        int month = date.getMonthValue();
        int today = date.getDayOfMonth();

        // 将date设置为这个月的第一天,并得到这一天为星期几
        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 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.printf("*");
            }else{
                System.out.printf(" ");
            }
            date = date.plusDays(1);
            if (date.getDayOfWeek().getValue() == 1){
                System.out.println();
            }
        }
        if (date.getDayOfWeek().getValue() != 1){
            System.out.println();
        }
    }
}
posted @ 2021-01-24 22:25  张三丰学Java  阅读(741)  评论(0编辑  收藏  举报