聽說你還在用SimpleDateFormat格式化日期

2020-12-14 Java技術架構

作者:程式設計師內點事

說在前邊

最近部門幾位同事受了一些委屈相繼離職,共事三年臨別之際頗有不舍,待一切手續辦妥帖,寒暄過後送他們出公司,幾個老哥臨別時衝我鬼魅一笑,我頓時心裡一緊有種不好的預感,這事絕對沒有這麼簡單。等我接手這幾個大佬的項目後,應驗了我的預感,此刻我居然有點後悔,為啥送別之時沒揍他們一頓!哈哈哈~ 而這種打人的衝動,在我開始優化幾位老哥的項目時候,變得越來越強烈。

有個坑

技術部每個月都會組織一下代碼走查及優化,以前是各自審查優化自己的項目,如今幾位老哥的離職他們的項目就落到了我的頭上。對於程式設計師來說最痛苦的事情就是接手別人的項目,還要做優化改造,因為這一點也不比重構一遍項目簡單。不過,軍令在前,沒辦法硬著頭皮上吧!

第一個優化的點就讓我有點崩潰,這幾個大佬的技能能力很強,一直都是我學習的榜樣,但在項目裡幾乎所有的日期格式化都這樣用 SimpleDateFormat ,像如下代碼這樣實現,emm~ ,受過傷的男人怎麼啥事都做的出來,哈哈哈~

SvcOrderDailyStatisticsPo orderDailyStatisticsPo = new SvcOrderDailyStatisticsPo();SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");Date stationTime = dateFormat.parse(dateFormat.format(svcWorkOrderPo.getPayEndTime()));orderDailyStatisticsPo.setStatisticalDate(stationTime);而且項目中的時間和日期API用的也比較混亂,考慮到 java.util.Date 和 java.util.Calendar 不支持時區,且非線程安全,對於日期的計算相對繁瑣,技術部一致要求用JDK1.8以後的 java.time LocalDateTime。但不少人還是在用 java.util.Date 和 java.util.Calendar 處理日期。

優化方案

時間格式化是使用頻率非常高的,如何讓時間格式化變得既簡單又不用重複造輪子,那麼就應將它抽象出來,作為全局的日期格式化處理,下面就結合實踐簡單介紹下幾種優化方案。

測試地址:http://127.0.0.1:8080/timeTest

@GetMapping("/timeTest")public OrderInfo timeTest() { OrderInfo order = new OrderInfo(); order.setCreateTime(LocalDateTime.now()); order.setUpdateTime(new Date()); return order; }1、@JsonFormat註解

使用@JsonFormat註解格式化時間,應該算是一個基本操作了,大部分開發者都應用此種方式,簡單方便。

/** * @Author: xiaofu * @Description: */public class OrderInfo { @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime; @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") private Date updateTime; public LocalDateTime getCreateTime() { return createTime; } public void setCreateTime(LocalDateTime createTime) { this.createTime = createTime; } public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; }}測試一下結果,發現 Date 類型和 LocalDateTime 類型都格式化成功,但還是有個問題,這樣做仍然比較繁瑣,每個實體類的日期欄位都要加@JsonFormat註解,重複的工作量也不小。接著往下看~

2、全局配置 (1)

Springboot 已經為我們提供了日期格式化 ${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss},這裡我們需要進行全局配置,配置比較簡單,也無需在實體類屬性上添加@JsonFormat註解。

/** * @Author: xiaofu * @Description: */public class OrderInfo { //@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime; //@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") private Date updateTime; public LocalDateTime getCreateTime() { return createTime; } public void setCreateTime(LocalDateTime createTime) { this.createTime = createTime; } public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; }}只需要用@Configuration定義一個配置類,注入兩個Bean即可完成全局日期格式化處理,這種方式也是當前我項目中正在用的方式。

/** * @Author: xiaofu * @Description: */@Configurationpublic class LocalDateTimeSerializerConfig { @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}") private String pattern; @Bean public LocalDateTimeSerializer localDateTimeDeserializer() { return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern)); } @Bean public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { return builder -> builder.serializerByType(LocalDateTime.class, localDateTimeDeserializer()); }}這種方式可支持 Date 類型和 LocalDateTime 類型並存,那麼有一個問題就是現在全局時間格式是yyyy-MM-dd HH:mm:ss,但有的欄位卻需要yyyy-MM-dd格式咋整?

那就需要配合@JsonFormat註解使用,在特定的欄位屬性添加@JsonFormat註解即可,因為@JsonFormat註解優先級比較高,會以@JsonFormat註解標註的時間格式為主。

3、全局配置 (2)

這種全局配置的實現方式與上邊的效果是一樣的,不過,要注意的是使用這種配置後,欄位手動配置@JsonFormat註解將不再生效。

/** * @Author: xiaofu * @Description: */public class OrderInfo { //@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime; //@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") private Date updateTime; public LocalDateTime getCreateTime() { return createTime; } public void setCreateTime(LocalDateTime createTime) { this.createTime = createTime; } public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; }}/** * @Author: xiaofu * @Description: */@Configurationpublic class LocalDateTimeSerializerConfig { @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)); } }}總結

分享了一個Springboot項目開發過程中的一個小技巧,也順便吐槽一下項目優化中遇到的坑,優化別的人的代碼雖然是一件比較痛苦的事情,但在這個過程中確實能學習到很多技巧,對個人的技能提升也是很有幫助,因為都是些能夠實實在在提高開發效率的乾貨。

來源:掘金 連結:https://juejin.im/post/5e940626e51d4546f5790979

相關焦點

  • 2020 年,你還在使用 Java 中的 SimpleDateFormat 嗎?
    作者 | 阿文責編 | 屠敏今天我和大家一起聊一聊SimpleDateFormat ,這都2020年了,怎麼還在用SimpleDateFormat ?這個時候我們就會使用到SimpleDateFormat 類,比如使用下面的代碼來獲取當前時間,並調用SimpleDateFormat 對時間進行格式化:Date date = newDate(); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//設置日期格式
  • java中date日期計算使用方法
    接下來我們需要使用到一個格式化類,先對他進行初始化:SimpleDateFormat temp=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");使用simpleDateFormat類進行對時間操作。
  • java中定義日期格式的轉換符
    =String.format(Locale.US,"英文月份簡稱:%tb",date);System.out.println(str);System.out.printf("本地月份簡稱:%tb%n",date);//B的使用,月份全稱str
  • 柳小白Python學習筆記 23 xlrd6日期讀取
    為什麼用「0:11」來分片呢?數的23-0-1例子的輸出結果。這種方法看起來挺好用的,但是如果遇到的是以xlrd.xldate_as_tuple()函數輸出的元組格式會怎麼樣呢?1.2 對用元組格式轉化的字符串進行分片
  • xk-time 1.1.0 發布,Java 時間工具包,增加模糊解析日期功能
    時間轉換,計算,格式化,解析,日曆和cron表達式等的工具,使用java8,線程安全,簡單易用,多達20幾種常用日期格式化模板。0.為什麼要開發這個工具?(1)java8以前的Date API設計不太好,使用不方便,往往會有線程安全問題。
  • C#日期格式化的幾種處理方法 - 51CTO.COM
    C#日期格式化的幾種處理方法 本文將介紹幾種C#日期格式化的處理方法,包括綁定時格式化日期方法、用String類轉換日期顯示格式、用Convert方法轉換日期顯示格式等等 作者:webfly
  • 兩個日期相差多少天,你還在一天天的數嗎?用Excel輕鬆完成計算
    語法:DATEDIF(start_date,end_date,unit)參數:start_date:必需,表示給定期間的第一個或開始日期的日期。日期值有多種輸入方式:帶引號的文本字符串、序列號或其他公式或函數的結果。end_date:必需,用於表示時間段的最後一個(即結束)日期的日期。Unit:您希望返回的信息類型,其中:"Y" 一段時期內的整年數。"M" 一段時期內的整月數。
  • 如何在Element框架使用日期控制項並獲取年齡
    技術vueelementJavaScriptCSS3在element框架項目中,日期控制項是一種常用的,可以顯示日期、時間和日期時間。那麼,如何使用日期控制項設置用戶出生日期?然後根據出生日期算出年齡。下面利用實例說明:操作步驟如下:1、打開HBuilderX工具,創建vue項目,然後新建vue文件
  • 為什麼說用PHP開發大型系統令人不爽
    但是十次有九次,你想要在PHP腳本中使用這種模塊,但這又使你的腳本不能合適Apache的多線程模式。這也是為什麼PHP小組不推薦在Apache 2 的多線程模式下運行PHP。不良的多線程模式支持使PHP常被認為是Apache 2依然不流行的原因之一。  請閱讀這篇討論: Slashdot: Sites Rejecting Apache 2?.  3.
  • 你知道to date是什麼意思嗎?
    說到date這個單詞,很多人會想到日期、日子,其實,date除了做名詞還可以做動詞。今天,我們就一起來看一下date的用法。首先,我們看一下date做名詞的用法。1、Write today's date at the top of the page.在頁面頂端寫上今天的日期。這句話中date的意思是日期、日子,是一個可數名詞。2、The details can be added at a later date .細節可過些時候再補充進去。
  • 在Java中使用日期格式的簡單示例
    假設1119280000000L大約是從1970年1月1日到2005年6月20日的毫秒數,並且您要使用長格式(LONG style)以德語列印該日期,這樣「 June」將顯示為「 Juni」。importjava.text.*;import java.util.
  • shell腳本的使用該熟練起來了,你說呢?(篇三)
    /hello_shell.sh 執行腳本,當前目錄下就會生成一個 lynfile 文件,裡面的內容為It is a test7.原樣輸出字符串,不進行轉義或取變量(用單引號)echo '$name\"'8.顯示命令執行結果echo `date
  • 兩個日期之間有多少個星期天,不用一個個數,用Excel就能計算
    【語法】TEXT(value,format_text)【參數】value是數值、計算結果是數值的公式、或對數值單元格的引用;format_text是所要選用的文本型數字格式,上圖公式中"aaaa"代表星期幾。