關于date4j,簡約的日期處理庫(Java's Date Classes Must Die.)
在熟悉公司業務代碼的時候經常看見有日期處理(date),由于項目轉手次數較多,在這方面沒合理封裝處理好,于是就想自己封裝一個date類。然而輾轉了幾天卻發覺已經有date4j的存在,于是在這里簡單地介紹一下這個日期類庫。以下包括自己的代碼、網上流傳資料、以及date4j官網例子。
-------------------------------------------------------------------------------------------------------------------------------------------------------------
java日期處理相關類:
java.sql.Date
java.sql.Time
java.sql.Timestamp
java.util.Calendar
java.util.TimeZone
比較常用的是java.util.date,將java.util.Date轉為java.sql.Date的時候,日期時分秒會被去掉,失去精度。而且如果現在翻開api看看就發覺這兩個類好多方法已經過時,幾近淪為廢物。
Timestamp能和java.util.date無損轉換,但是在一些預定義sql中會常常出問題。
(以上出自 click me)
--------------------------------------------------------------------------------------------------------------------------------------------------------------
Joda Time | Date4j |
---|---|
擁有的類的數量: 140+ | 擁有的類的數量< 10 |
包含可變和不可變類 | 僅包含不可變類 |
強調速度和功能 | 強調簡單和有效 |
支持格里高里歷(Gregorian)、 科普特語日歷(Coptic)、 伊斯蘭教歷(Islamic)、佛歷(Buddhist)等等 | 只提供對格里高里歷的支持 |
可以完全取代JDK日期類 | 和JDK日期類配合使用 |
精確到毫秒級操作 | 支持到納秒(十億分之一秒)級操作 |
修復了天“溢出”的問題 | 天“溢出”的問題可配置 |
針對的是通常意義的日期維護 | 適用于通過數據庫來維護的日期 |
采用Apache 2.0授權許可 | 采用BSD授權許可 |
雖然乍一看Date4j只具備了Joda中一部分的特性,但它有兩個主要的特點是Joda所不具備的。
首先,Date4j的開發者宣稱類庫不應莫名其妙地將日期截斷。Joda只支持毫秒級的精度而且在將來可能也不會改善。一些數據庫也已經有了更好的解決方案。比如流行的PostgreSQL數據庫對時間戳精度就已經支持到微秒級(百萬分之一秒)。Date4j可在處理日期時對精度毫無損傷。
第二個特征是日期“溢出”的問題,例如向某個日期增加一段時間后,日期落在下月的情況。最簡單的例子就是在3月31日增加一個月的計算:
DateTime dt = new DateTime("2011-03-31");
DateTime result = dt.plusMonths(1); (最新版本此方法應該已經被刪除,只有plus(...)與plusDay())
System.out.println(result.toString());
當使用Joda Time時,會輸出4月30日,但這也許并不是你想要的結果。
鑒于這種不確定性,Date4j為您提供了4種選擇:
1. | 第一天 |
2. | 最后一天(與Joda Time相同) |
3. | 日期順延 |
4. | 拋出異常 |
以上轉自 click me
-----------------------------------------------------------------------------------------------------------------------------------------------------------
date4j官網&&實例:
import hirondelle.date4j.DateTime;
import hirondelle.date4j.DateTime.DayOverflow;
import java.util.TimeZone;
public class Date4jExamples {
public static void main(String[] args) {
Date4jExamples examples = new Date4jExamples();
examples.currentDateTime();
examples.ageIfBornOnCertainDate();
examples.daysTillChristmas();
examples.whenIs90DaysFromToday();
examples.dateDifference();
examples.whenIs3Months5DaysFromToday();
examples.hoursDifferenceBetweenParisAndPerth();
examples.weeksSinceStart();
examples.timeTillMidnight();
examples.imitateISOFormat();
examples.firstDayOfThisWeek();
examples.jdkDatesSuctorial();
}
private static void log(Object aMsg) {
System.out.println(String.valueOf(aMsg));
}
/**
* 獲取當前時間 what is the current date-time in the JRE's default time zone
* ------------------------------------------------------------------------
* Here are some practical examples of using the above formatting symbols:
* Format Output
* YYYY-MM-DD hh:mm:ss.fffffffff a 1958-04-09 03:05:06.123456789 AM
* YYYY-MM-DD hh:mm:ss.fff a 1958-04-09 03:05:06.123 AM
* YYYY-MM-DD 1958-04-09
* hh:mm:ss.fffffffff 03:05:06.123456789
* hh:mm:ss 03:05:06
* YYYY-M-D h:m:s 1958-4-9 3:5:6
* WWWW, MMMM D, YYYY Wednesday, April 9, 1958
* WWWW, MMMM D, YYYY |at| D a Wednesday, April 9, 1958 at 3 AM
*
* ---
private void currentDateTime() {
DateTime now = DateTime.now(TimeZone.getDefault());
String result = now.format("YYYY-MM-DD hh:mm:ss");
log("Current date-time in default time zone : " + result);
// result Current date-time in default time zone : 2012-04-12 00:55:54
}
/**
* 年齡計算 what's the age of someone born may 16,1995
*/
private void ageIfBornOnCertainDate() {
DateTime today = DateTime.today(TimeZone.getDefault());
DateTime birthdate = DateTime.forDateOnly(1995, 5, 16);
int age = today.getYear() - birthdate.getYear();
// getDayOfYear獲取距離年初的總天數
if (today.getDayOfYear() < birthdate.getDayOfYear()) {
age = age - 1;
}
log("Age of someone born May 16, 1995 is : " + age);
// result Age of someone born May 16, 1995 is : 16
}
/**
* 日期相距 How many days till the next December 25
*/
private void daysTillChristmas() {
DateTime today = DateTime.today(TimeZone.getDefault());
DateTime christmas = DateTime.forDateOnly(today.getYear(), 12, 25);
int result = 0;
if (today.isSameDayAs(christmas)) {
// do nothing
} else if (today.lt(christmas)) {
result = today.numDaysFrom(christmas);
} else if (today.gt(christmas)) {
DateTime christmasNextYear = DateTime.forDateOnly(
today.getYear() + 1, 12, 25);
result = today.numDaysFrom(christmasNextYear);
}
log("Number of days till Christmas : " + result);
// result Number of days till Christmas : 257
}
/**
* What day is 90 days from today
*/
private void whenIs90DaysFromToday() {
DateTime today = DateTime.today(TimeZone.getDefault());
log("90 days from today is : "
+ today.plusDays(90).format("YYYY-MM-DD"));
// result 90 days from today is : 2012-07-11
}
/**
* 日期相差
*/
private void dateDifference() {
// DayOverflow.Abort result throw Exception
// DayOverflow.Spillover result 2011-05-01
// DayOverflow.LastDay result 2011-04-30
// DayOverflow.FirstDay result 2011-05-01
// public enum DayOverflow {
/** Coerce the day to the last day of the month. */
// LastDay,
/** Coerce the day to the first day of the next month. */
// FirstDay,
/** Spillover the day into the next month. */
// Spillover,
/** Throw a RuntimeException. */
// Abort;
// }
/**
* @param aNumYears
* positive, required, in range 0

* @param aNumMonths
* positive, required, in range 0

* @param aNumDays
* positive, required, in range 0

* @param aNumHours
* positive, required, in range 0

* @param aNumMinutes
* positive, required, in range 0

* @param aNumSeconds
* positive, required, in range 0

* aNumYears, Integer aNumMonths, Integer aNumDays, Integer
* aNumHours, Integer aNumMinutes, Integer aNumSeconds,
* DayOverflow aDayOverflow)
*
*/
DateTime dt = new DateTime("2011-03-31");
DateTime result = dt.plus(0, 1, 0, 0, 0, 0, DayOverflow.Spillover);
log("date difference : " + result.toString());
// result date difference : 2011-05-01 00:00:00
}
/** What day is 3 months and 5 days from today? */
private void whenIs3Months5DaysFromToday() {
DateTime today = DateTime.today(TimeZone.getDefault());
DateTime result = today.plus(0, 3, 5, 0, 0, 0,
DateTime.DayOverflow.FirstDay);
log("3 months and 5 days from today is : "
+ result.format("YYYY-MM-DD"));
// result 3 months and 5 days from today is : 2012-07-17
}
/**
* Current number of hours difference between Paris, France and Perth,
* Australia.
*/
private void hoursDifferenceBetweenParisAndPerth() {
// this assumes the time diff is a whole number of hours; other styles
// are possible
DateTime paris = DateTime.now(TimeZone.getTimeZone("Europe/Paris"));
DateTime perth = DateTime.now(TimeZone.getTimeZone("Australia/Perth"));
int result = perth.getHour() - paris.getHour();
if (result < 0) {
result = result + 24;
}
log("Numbers of hours difference between Paris and Perth : " + result);
// result Numbers of hours difference between Paris and Perth : 6
}
/** How many weeks is it since Sep 6, 2010? */
private void weeksSinceStart() {
DateTime today = DateTime.today(TimeZone.getDefault());
DateTime startOfProject = DateTime.forDateOnly(2010, 9, 6);
int result = today.getWeekIndex() - startOfProject.getWeekIndex();
log("The number of weeks since Sep 6, 2010 : " + result);
// result The number of weeks since Sep 6, 2010 : 83
}
/** How much time till midnight? */
private void timeTillMidnight() {
DateTime now = DateTime.now(TimeZone.getDefault());
DateTime midnight = now.plusDays(1).getStartOfDay();
long result = now.numSecondsFrom(midnight);
log("This many seconds till midnight : " + result);
// result This many seconds till midnight : 83046
}
/** Format using ISO style. */
private void imitateISOFormat() {
DateTime now = DateTime.now(TimeZone.getDefault());
log("Output using an ISO format: " + now.format("YYYY-MM-DDThh:mm:ss"));
// result Output using an ISO format: 2012-04-12T00:55:54
}
private void firstDayOfThisWeek() {
DateTime today = DateTime.today(TimeZone.getDefault());
DateTime firstDayThisWeek = today; // start value
int todaysWeekday = today.getWeekDay();
int SUNDAY = 1;
if (todaysWeekday > SUNDAY) {
int numDaysFromSunday = todaysWeekday - SUNDAY;
firstDayThisWeek = today.minusDays(numDaysFromSunday);
}
log("The first day of this week is : " + firstDayThisWeek);
// result The first day of this week is : 2012-04-08
}
/** For how many years has the JDK date-time API been suctorial? */
private void jdkDatesSuctorial() {
DateTime today = DateTime.today(TimeZone.getDefault());
DateTime jdkFirstPublished = DateTime.forDateOnly(1996, 1, 23);
int result = today.getYear() - jdkFirstPublished.getYear();
log("The number of years the JDK date-time API has been suctorial : "
+ result);
// result The number of years the JDK date-time API has been suctorial :
// 16
}
}
posted on 2012-04-12 01:05 kohri 閱讀(2836) 評論(0) 編輯 收藏 所屬分類: JAVA