首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java Calendar月份陷阱:0-11對應1-12月導致時間計算錯誤

     編輯:程式設計綜合問答

代碼中`c.set(2015, 10, 25)`實際設置為**2015年11月25日**,因`Calendar.MONTH`字段**0-11對應1-12月**。兩個本應相同時間的毫秒值相減得到-31天(-2678400000毫秒)。本文詳解月份陷阱及避坑指南。

錯誤代碼還原


Calendar c = Calendar.getInstance();
c.set(2015, 10, 25); // 意圖:2015-10-25,實際:2015-11-25
long t1 = c.getTimeInMillis();

Calendar today = Calendar.getInstance(); // 假設今天 2015-10-25
long diff = today.getTimeInMillis() - t1; // -31天

Calendar月份常量表

常量值月份
`Calendar.JANUARY`01月
`Calendar.FEBRUARY`12月
.........
`Calendar.OCTOBER`910月
`Calendar.NOVEMBER`1011月
`Calendar.DECEMBER`1112月

正確用法三種

  1. 使用常量(推薦,可讀性最強):
    c.set(2015, Calendar.OCTOBER, 25); // 明確10月
  2. 月份-1(若用變量/字面量):
    int month = 10; // 10月
    c.set(2015, month - 1, 25);
  3. Java 8+ java.time.LocalDate(徹底替代Calendar):
    
    LocalDate date = LocalDate.of(2015, 10, 25); // 直觀、不可變、線程安全
    long diff = ChronoUnit.DAYS.between(LocalDate.now(), date); // 直接得天數差
    

Calendar其他易錯字段

字段範圍陷阱
`DAY_OF_WEEK`1-71=星期日,7=星期六(非ISO標準)
`WEEK_OF_YEAR`1-53週邊界取決於Locale
`HOUR`0-1112小時制,需配合`AM_PM`
`HOUR_OF_DAY`0-2324小時制,推薦用此

遷移建議:全面拥抱 java.time (JSR-310)

  • `LocalDate`/`LocalTime`/`LocalDateTime`:無時區日期時間。
  • `ZonedDateTime`/`OffsetDateTime`:帶時區/偏移。
  • `Instant`:時間戳(納秒精度)。
  • `Duration`/`Period`:時間間隔/日期間隔。
  • `DateTimeFormatter`:線程安全格式化/解析。
鐵律:Calendar月份0-based是歷史包袱,新代碼零成本遷移到java.time,舊代碼遇到月份計算必檢查-1。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved