1. 程式人生 > >一起來學SpringBoot ——JDK8 日期格式化

一起來學SpringBoot ——JDK8 日期格式化

為什麼要用新的日期型別

在 JDK8 中,一個新的重要特性就是引入了全新的時間和日期API,它被收錄在 java.time 包中。藉助新的時間和日期API可以以更簡潔的方法處理時間和日期。

在 JDK8 之前,所有關於時間和日期的API存在以下幾個缺陷,也正是這些缺陷,出現了很多第三方的日期處理框架,例如 Joda-Timedate4j 等開源專案。但是,Java 需要一套標準的用於處理時間和日期的框架,於是乎在 JDK8 中引入了新的日期API。遵循 JSR-310 規範的實現,而 Joda-Time

 框架的作者正是 JSR-310 的規範的倡導者,所以用過 Joda-Time 的對新日期API也不會陌生。

缺陷

  • 之前的 java.util.Date 和 java.util.Calendar 類易用性差,不支援時區,且非執行緒安全的;

  • 日期格式化類 java.text.DateFormat 是一個抽象類,使用時需要先例項化一個 SimpleDateFormat 物件來處理日期格式化,同時 DateFormat 也不是執行緒安全的,這意味著如果你在多執行緒程式中呼叫同一個 DateFormat

     物件,會得到意想不到的結果。

  • 對日期的計算方式繁瑣,而且容易出錯,因為月份是從0開始的,從 Calendar 中獲取的月份需要加一才能表示當前月份。

為什麼要格式化

說了這麼多,和 Spring Boot 有什麼關係呢?不要急,待我娓娓道來!

  • 格式化前:{"payTime":"2018-09-30T09:51:56.77"}

  • 格式化後:{"payTime":"2018-09-30 09:51:56"}

都知道我們國人習慣 yyyy-MM-dd HH:mm:ss 這種格式的日期,但奈何框架是歪國大佬們寫的,他們的日期格式與我們相差甚遠,好在 Spring Boot

 提供了 spring.jackson.date-format,奈何它只能格式化 java.util.Date。那麼解決辦法是什麼呢?

匯入依賴

首先一個 WEB 專案,必不可少的依賴就是 spring-boot-starter-web 了,一路學習下來的小夥伴們肯定都熟記於心了

image.png

配置檔案

由於 spring.jackson.date-format 對新的日期型別不在有效果,所以這裡0配置檔案了

方案一(強烈推薦)

只需要定義一個配置類,在裡面定義兩個 Bean 即可完成全域性日期格式化處理,這種方式也是本人現在使用的,同時還兼顧了 Date 和 LocalDateTime 並存

image.png

方案二(強烈推薦)

有時候,我們對日期格式要做特殊的處理,全域性的格式化方式無法滿足我們需求是,使用該方案是非常好的選擇,通過 @JsonFormat 註解我們可以更為精準的為日期欄位格式化,它也是優先順序最高的

image.png

方案三(可選)

其實和第一種類似,只不過第一種的寫法更加優雅簡潔,如果有多種型別需要做統一格式化處理,這種方案也不是不可以考慮

package com.battcn.config;import com.fasterxml.jackson.core.JsonGenerator;import com.fasterxml.jackson.core.JsonParser;import com.fasterxml.jackson.databind.*;import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;import java.io.IOException;import java.time.LocalDate;import java.time.LocalDateTime;import static java.time.format.DateTimeFormatter.ofPattern;/** * @author Levin * @since 2018/9/30 0030 */@Configurationpublic class LocalDateTimeSerializerConfig1 {    @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")    private String pattern;    @Bean    @Primary    public ObjectMapper serializingObjectMapper() {        ObjectMapper objectMapper = new ObjectMapper();        JavaTimeModule javaTimeModule = new JavaTimeModule();        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());        objectMapper.registerModule(javaTimeModule);        return objectMapper;    }    public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {        @Override        public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {            gen.writeString(value.format(ofPattern(pattern)));        }    }    public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {        @Override        public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext) throws IOException {            return LocalDateTime.parse(p.getValueAsString(), ofPattern(pattern));        }    }


控制層

定義了一個很簡單的響應

package com.battcn.controller;import com.battcn.pojo.Order;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.time.LocalDateTime;/**
 * @author Levin
 * @since 2018/8/2 0002
 */@[email protected]("/orders")public class OrderController {    @GetMapping
    public Order query() {
        Order order = new Order();
        order.setPayTime(LocalDateTime.now());        return order;
    }
}

主函式

package com.battcn;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/**
 * @author Levin
 */@SpringBootApplicationpublic class Chapter28Application {    public static void main(String[] args) {
        SpringApplication.run(Chapter28Application.class, args);
    }
}

測試

完成準備事項後,啟動Chapter28Application,訪問 http://localhost:8080/orders 即可看到格式化後的日期啦...

總結

目前很多大佬都寫過關於 SpringBoot 的教程了,如有雷同,請多多包涵,本教程基於最新的 spring-boot-starter-parent:2.0.3.RELEASE編寫,包括新版本的特性都會一起介紹...

給大家推薦一個程式設計師學習交流群:863621962。群裡有分享的視訊,還有思維導圖

群公告有視訊,都是乾貨的,你可以下載來看。主要分享分散式架構、高可擴充套件、高效能、高併發、效能優化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分散式專案實戰學習架構師視訊。