JDK Date/Calendar 設計缺陷眾多:可變、線程不安全、API 反人類(月份 0-11)、無時間段計算類。Joda-Time 作為業界標準替代品(Java 8 前),API 設計優雅、不可變、線程安全、功能豐富。Java 8 java.time 包即基於其設計。
| Joda-Time | JDK 對應 | 說明 |
|---|---|---|
Instant | Date | 時間線上的瞬間(毫秒值) |
DateTime | Calendar | 完整日期時間(年歷) |
DateTimeZone | TimeZone | 時區 |
DateTimeFormatter | DateFormat | 格式化/解析 |
LocalDate/LocalTime | 無 | 純日期/純時間(無時區) |
Period/Duration | 無 | 時間段(年月日/毫秒級) |
所有核心類均為 不可變,修改操作返回新對象,支持鏈式調用(流暢接口),代碼極其簡潔。
DateTime now = new DateTime(); // 當前
DateTime dt = new DateTime(2016, 8, 18, 15, 20, 47, 345); // 指定年月日時分秒毫秒
dt.getYear(); // 2016
dt.getMonthOfYear(); // 8
dt.getDayOfMonth(); // 18
dt.getHourOfDay(); // 15
dt.getMinuteOfHour(); // 20
dt.getSecondOfMinute(); // 47
dt.getMillisOfSecond(); // 345
dt.getDayOfWeek(); // 4 (周四)
// 直接 toString
dt.toString("yyyy-MM-dd HH:mm:ss"); // 2016-08-18 15:20:47
// 專用格式化器(線程安全,可復用)
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");
fmt.print(dt); // 格式化
fmt.parseDateTime(str); // 解析
// 絕對設置
dt = dt.withHourOfDay(15).withMinuteOfHour(20);
// 相對增減
dt = new DateTime().plusHours(3).plusMinutes(5);
// 今天 0 點
dt = new DateTime().withMillisOfDay(0);
// 下周二上午 10 點
dt = new DateTime().plusWeeks(1).withDayOfWeek(2).withMillisOfDay(0).withHourOfDay(10);
// 明天最後一刻
dt = new DateTime().plusDays(1).millisOfDay().withMaximumValue(); // 23:59:59.999
// 本月最後一天最後一刻
dt = new DateTime().dayOfMonth().withMaximumValue().millisOfDay().withMaximumValue();
// 兩時間差(年月日時分秒)
Period p = new Period(start, end);
p.getMonths() + "月" + p.getDays() + "天" + p.getHours() + "時" + p.getMinutes() + "分";
// 專用單位類
int age = Years.yearsBetween(born, DateTime.now()).getYears(); // 年齡
int lateMin = Minutes.minutesBetween(LocalTime.now().withHourOfDay(9), LocalTime.now()).getMinutes(); // 遲到分鐘
LocalDate born = new LocalDate(1990, 11, 20);
int age = Years.yearsBetween(born, LocalDate.now()).getYears();
int lateMin = Minutes.minutesBetween(new LocalTime(9,0), LocalTime.now()).getMinutes();
// JDK -> Joda
new DateTime(new Date());
new DateTime(Calendar.getInstance());
LocalDate.fromDateFields(new Date());
// Joda -> JDK
dt.toDate();
dt.toCalendar(Locale.CHINA);
localDate.toDate();
DateTimeFormat) 單獨負責創建格式化器。LocalDate/LocalTime/Period/Duration 精準對應業務概念。Joda-Time 是 Java 時間處理的「正確姿勢」。Java 8+ 專案請直接使用 java.time(API 幾乎一致),舊專案引入 Joda-Time 即可徹底解決日期時間痛點。