天天看點

jdk1.8的新特性——時間日期之LocalDateTime

在上一篇jdk1.8的新特性——時間日期之LocalTime中,我們學習了LocalTime的API使用,其中更加全面得講解了如何建立一個LocalTime對象,并且初步學會了DateTimeFormatter的使用,将時間的格式轉化成我們想要的字元表達式。同時,我們結合LocalDate對象,在LocalTime對象的基礎上“合成”了一個LocalDateTime對象。那麼這個LocalDateTime對象有哪些方法需要我們掌握,現在就讓我們開始LocalDateTime的學習吧。:D

首先,如何擷取或者建立一個LocalDateTime對象,常見的方法有:

public static void main(String[] args) {

        //擷取目前日期時間對象:2019-08-13T10:15:20,withNano(0)去掉毫秒數
        LocalDateTime localDateTime = LocalDateTime.now().withNano(0);

        //擷取日期對象:2019-08-13
        LocalDate today = LocalDate.now();
        //建立時間對象:10:15:20
        LocalTime now = LocalTime.of(10, 15, 20);
        //建立LocalDateTime對象:2019-08-13T10:15:20
        LocalDateTime dateTime = LocalDateTime.of(today, now);

        //定義日期時間格式:yyyy年MM月dd日HH點mm分ss秒
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH點mm分ss秒");
        //新中國成立的日期時間對象:1949-10-01T14:00
        LocalDateTime birthdayOfPRC = LocalDateTime.parse("1949年10月01日14點00分00秒", dateTimeFormatter);
    }
           

這些方法都在上一篇中有過介紹,上一篇的最後我們定義過DateTimeFormmatter,然後根據LocalTime的執行個體方法format,将時間進行了格式化。那麼,格式化後的字元能不能重新變成一個LocalTime對象呢?答案是肯定的,在上面代碼中parse方法就是将一個日期時間字元按照給定的dateTimeFormatter格式進行解析,當然這個字元串要符合這個dateTimeFormatter格式。

接下來,我們看看from方法如何擷取一個LocalDateTime對象。這也是我們上一篇遺留的一個知識點。在學習這個方法之前,我們需要先看看它的源代碼,不然就是一頭霧水。

/**
     * Obtains an instance of {@code LocalDateTime} from a temporal object.
     * <p>
     * This obtains an offset time based on the specified temporal.
     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
     * which this factory converts to an instance of {@code LocalDateTime}.
     * <p>
     * The conversion extracts and combines the {@code LocalDate} and the
     * {@code LocalTime} from the temporal object.
     * Implementations are permitted to perform optimizations such as accessing
     * those fields that are equivalent to the relevant objects.
     * <p>
     * This method matches the signature of the functional interface {@link TemporalQuery}
     * allowing it to be used as a query via method reference, {@code LocalDateTime::from}.
     *
     * @param temporal  the temporal object to convert, not null
     * @return the local date-time, not null
     * @throws DateTimeException if unable to convert to a {@code LocalDateTime}
     */
    public static LocalDateTime from(TemporalAccessor temporal) {
        if (temporal instanceof LocalDateTime) {
            return (LocalDateTime) temporal;
        } else if (temporal instanceof ZonedDateTime) {
            return ((ZonedDateTime) temporal).toLocalDateTime();
        } else if (temporal instanceof OffsetDateTime) {
            return ((OffsetDateTime) temporal).toLocalDateTime();
        }
        try {
            LocalDate date = LocalDate.from(temporal);
            LocalTime time = LocalTime.from(temporal);
            return new LocalDateTime(date, time);
        } catch (DateTimeException ex) {
            throw new DateTimeException("Unable to obtain LocalDateTime from TemporalAccessor: " +
                    temporal + " of type " + temporal.getClass().getName(), ex);
        }
    }
           

這個方法我們直接讀代碼,就不翻譯注釋了。方法參數是一個TemporalAccessor對象(TemporalAccessor:時間通路器),從源碼中可以知道TemporalAccessor是個接口,那既然是接口,這個temporal對象就應該是實作類的對象(關于時間、日期、日期時間、瞬時、時區日期時間等的類都實作TemporalAccessor)。從代碼中可以看出,程式先對這個temporal對象進行instanceof判斷,也就是說先判斷temporal是不是LocalDateTime、ZonedDateTime、OffsetDateTime三者中的一個執行個體。如果是,直接強制轉換後使用toLocalDateTime方法。如果不是三者之一的執行個體,就從這個temporal中擷取LocalDate的date對象和LocalTime的time對象,再new一個LocalDateTime對象傳回。這個地方我們可以看到上一篇中沒有講解得LocalTime的from辦法,我們可以繼續進入這個from方法看看。

public static LocalTime from(TemporalAccessor temporal) {
        Objects.requireNonNull(temporal, "temporal");
        LocalTime time = temporal.query(TemporalQueries.localTime());
        if (time == null) {
            throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: " +
                    temporal + " of type " + temporal.getClass().getName());
        }
        return time;
    }
           

可以看到"LocalTime time = temporal.query(TemporalQueries.localTime());" 這句代碼是從temporal中查詢出LocalTime對象,那我們現在還要不要繼續跟進這個方法呢?答案在于你自己。:D

2019/08/24更

我這樣寫到底對不對,該不該花那麼大力氣去讀源碼,去了解。或是找個例子看看,知道怎麼用就行了。那樣無疑很快,很高效,這種成熟的API有沒有必要去讀源碼。讀源碼的時候,耗時是肯定的,有些單詞不認識就需要查,有些不懂的地方就要去思考。不過,收獲也是肯定比較多,比如怎麼更好的設計接口,抽象類。源碼就好比作文中的範文一樣,無論注釋,方法命名,還是通路控制符的設計,各個關鍵字用得都很精準嚴謹。對我程式設計有很大的啟迪作用,可是目前的國内環境(除了大廠的一些部門)就是不重視代碼品質,在部門中我一個人重視感覺力不從心,上司甚至說我沒有包容性,讓我學會相容,相容那些不規範。我也很無奈,隻能說自上而下的上司不重視長遠發展,隻顧眼前。但是如果完全的融入他們,我都瞧不起自己個兒。明知不對,還去做,那我成什麼人了。人生就是充滿着沖突,我改變不了他們,也不想變成他們那樣。那麼,我想隻有更好充實自己,然後尋找與我價值觀相近的公司。

大家可以從這個網站上繼續學習 https://www.yiibai.com/javatime

還有這篇部落格也不錯 https://blog.csdn.net/leolu007/article/details/53112363

如果有人想看更深入的内容,可以給我留言。我會考慮是否繼續深入地寫下去,再見!:D

繼續閱讀