关于date4j,简约的日期处理库(Java's Date Classes Must Die.) (一)

2014-11-24 07:40:09 · 作者: · 浏览: 1

在熟悉公司业务代码的时候经常看见有日期处理(date),由于项目转手次数较多,在这方面没合理封装处理好,于是就想自己封装一个date类。然而辗转了几天却发觉已经有date4j的存在,于是在这里简单地介绍一下这个日期类库。以下包括自己的代码、网上流传资料、以及date4j官网例子。


java日期处理相关类:

java.util.Date
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中会常常出问题。


Java本身的日期类在JDK1.0版本之后就再也没有更新过,同时还存在着一些众所周知的问题(例如1月从0开始,导致了很多月份差一的漏洞)。一份新的Java规范请求(JSR,Java Specification Request)已经被提交,目的就是要解决上述问题,此版本的类库仍处在Alpha版本。在其稳定之前,很多开发者还是会使用Joda Time类库,该类库与JSR-310的参考实现类似(但不完全相同)。 Date4j为在Java中处理日期提供了一套新的解决方案,但与Joda Time所关注的范围完全不同。对比如下:


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. 抛出异常


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