Like Share Discussion Bookmark Smile

J.J. Huang   2020-05-02   Java   瀏覽次數:

《阿里Java開發手冊》 | 編程規約 - 日期時間

【強制】日期格式化時,傳入 pattern 中表示年份統一使用小寫的 y。
說明:日期格式化時,yyyy 表示當天所在的年,而大寫的 YYYY 代表是 week in which year(JDK7 之後引入的概念),意思是當天所在的週屬於的年份,一周從周日開始,週六結束,只要本週跨年,返回的 YYYY 就是下一年。
正例:表示日期和時間的格式如下所示:
new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”)


【強制】在日期格式中分清楚大寫的M和小寫的m,大寫的H和小寫的h分別指代的意義。
說明:日期格式中的這兩對字母表意如下:

  • 表示月份是大寫的 M;
  • 表示分鐘則是小寫的 m;
  • 24 小時制的是大寫的 H;
  • 12 小時制的則是小寫的 h。

【強制】獲取當前毫秒數:System.currentTimeMillis(); 而不是 new Date().getTime()。
說明:如果想獲取更加精確的納秒級時間值,使用 System.nanoTime 的方式。在 JDK8 中,針對統計時間 等場景,推薦使用 Instant 類。


【強制】不允許在程序任何地方中使用:(1) java.sql.Date (2) java.sql.Time (3) java. sql.Timestamp。
說明:
第 1 個不記錄時間,getHours()拋出異常;第 2 個不記錄日期,getYear()拋出異常;第 3 個在構造方法super((time/1000)*1000),fastTime 和 nanos 分開存儲秒和納秒訊息。
反例:
java.util.Date.after(Date)進行時間比較時,當入參是 java.sql.Timestamp 時,會觸發 JDK BUG(JDK9 已修復),可能導致比較時的意外結果。


【強制】不要在程序中寫死一年為365天,避免在公曆閏年時出現日期轉換錯誤或程序邏輯錯誤。
正例:

1
2
3
4
// 獲取今年的天數
int daysOfThisYear = LocalDate.now().lengthOfYear();
// 獲取指定某年的天數
LocalDate.of(2011, 1, 1).lengthOfYear();

反例:

1
2
3
4
5
6
// 第一種情況:在閏年 366 天時,出現陣列越界異常
int[] dayArray = new int[365];
// 第二種情況:一年有效期的會員制,今年 1 月 26 日註冊,硬編碼 365 返回的卻是 1 月 25 日
Calendar calendar = Calendar.getInstance();
calendar.set(2020, 1, 26);
calendar.add(Calendar.DATE, 365);

【推薦】避免公曆閏年2月問題。閏年的2月份有29天,一年後的那一天不可能是2月29 日。


【推薦】使用枚舉值來指代月份。如果使用數字,注意Date,Calendar等日期相關類的月份 month 取值在 0-11 之間。
說明:參考 JDK 原生註解,Month value is 0-based. e.g., 0 for January.
正例: Calendar.JANUARY,Calendar.FEBRUARY,Calendar.MARCH 等來指代相應月份來進行傳參或 比較。


心得

看完這篇「日期時間」後,必須得說在 JDK8 以前,一直以來都是個問題,不管是日期的Format或是時區問題,常常踩到坑。

而這邊還特別提到了,一年365天的問題還有閏月的問題;這樣在設計開發與日期有關的邏輯時,可以更加以思考並考慮到未來可能發生的問題。

結語

文章越看越多,技術越學越多,就會發現自己的不足;技術學到後面都會想要將基礎再重新在打得更加扎實。

以前在開發覺得理所當然的事情,例如:命名規則、命名規範,照著別人怎麼說就怎麼做的想法,並沒有好好去想為什麼要這樣設計和規範。
於是乎同事們推薦《阿里巴巴Java開發手冊》來做閱讀,書中提到種種規範《正確範例》、《錯誤範例》還有解釋定義說明;我相信在閱讀完這一系列後,一定會更加扎實且實在。

如對此書有興趣,建議去購買官方認證的書籍,給予官方支持。

註:如有侵權,通知即刪。


註:以上參考了
Alibaba-Java-Coding-Guidelines Github
Alibaba-Java-Coding-Guidelines English Version