jodd之JDateTime

JDateTime是一个非常简洁、友好、精确的处理日期和时间的工具。它使用定义明确、并且久经考验的天文算法来进行时间操作。觉得JDK提供的Calendar很难用的人,会觉得JDateTime使用起来很方便。

Julian day(儒略日)

儒略日(Julian day)是指由公元前4713年1月1日,协调世界时中午12时开始所经过的天数,多为天文学家采用,用以作为天文学的单一历法,把不同历法的年表统一起来。如果计算相隔若干年的两个日期之间间隔的天数,利用儒略日就比较方便。官方文档上有更详细的描述,http://jodd.org/doc/jdatetime.html

精度

JDateTime使用Julian date来记录当前日期和时间。它使用天文算法来进行时间计算,这些算法已经被充分的使用和证明过了。JDateTime的精度为1毫秒。

设置日期和时间

JDateTime可以使用好几种方式初始化:①指定具体的日期(或者时间);②通过传递JDK提供的其他时间类型的对象;③通过指定时间戳(毫秒)等...

JDateTime可以通过指定具体日期/时间来初始化。初始化之后,还可以对其中的日期和时间进行更改。可以更改JDateTime对象中的所有时间属性,也可以只更改其中的一两项(比如小时、分钟)。

使用示例:

    JDateTime jdt = new JDateTime();            // 使用当前时间初始化
    jdt = new JDateTime(2012, 12, 21):          // 21st December 2012, midnight
    jdt = new JDateTime(System.currentTimeMillis());    // 当前时间
    jdt = new JDateTime(2012, 12, 21, 11, 54, 22, 124); // 21.Dec.2012,11:54:22.124
    jdt = new JDateTime("2012-12-21 11:54:22.124");     // -//-
    jdt = new JDateTime("12/21/2012", "MM/DD/YYYY");    // 21st Dec. 2012, midnight

通过set方法进行初始化:

    JDateTime jdt = new JDateTime();         // 当前时间
    jdt.set(2012, 12, 21, 11, 54, 22, 124);  // 21st December 2012, 11:54:22.124
    jdt.set(2012, 12, 21);                   // 21st December 2012, midnight
    jdt.setDate(2012, 12, 21);               // change just date to 21st Dec. 2012
    jdt.setCurrentTime();                    // set current date and time
    jdt.setYear(1973);                       // 修改年份
    jdt.setHour(22);                         // 修改小时
    jdt.setTime(18, 0, 12, 853);             // 修改时间部分

读取日期和时间

JDateTime类提供get方法来获取各种属性:years,months,hours等。Days和months属性都是整型数字,如JDateTime.JANUARY对应1.

除了get方法来获取单个属性,还提供方法来获取整个时间信息。
getDateTimeStamp()用来获取DateTimeStamp对象,getJulianDate()用来获取JulianDateStamp对象。

时间加减

JDateTime可以对当前时间进行增减,可以增减某个属性,或者一次增减全部属性。
使用样例:

jdt.add(1, 2, 3, 4, 5, 6, 7);  // 增加1年,2个月,3天,4个小时...
jdt.add(4, 2, 0);              // 增加4年,2个月
jdt.addMonth(-120);            // 减去120个月
jdt.subYear(1);                // 减去1年
jdt.addHour(1234);             // 减去1234个小时

注意:如果要增减多个属性,使用上面第一种方式比调用多次更加效率。

在增减月份的时候,可能会有一些意外的地方,如果当前日期是2003年1月31日,在当前日期上增加1个月,那结果是什么? 这里,JDateTime`提供两种结果。

JDateTime使用monthFix标志位来表示当前的处理方式。当monthFix为off时,一个月会被当成31天,所以上面的结果就是2003年1月31日,加上31天,结果为2003年3月3日。

monthFix为on(也是默认的方式)时,一个月就是单纯的一个月,不考虑一个月含有多少天。所以上面的结果就是2003年1月31日,加上一个月,结果为2003年2月28日。

因为这里可能会有非预期的结果,所以不推荐使用增减月份,推荐使用增减天数代替。

时间跨度

使用JDateTime可以很简单地计算出两个日期相差的天数,但是我们还有计算小时、分钟、秒、毫秒的需求;所以使用Period这个类是比较好的选择.

    JDateTime jDateTime = new JDateTime();
    JDateTime jDateTime1 = new JDateTime(2012, 1,31);
    Period period = new Period(jDateTime, jDateTime1);
    System.out.println(period.getHours());

类型转换

JDateTime可以很简单的转换成其他类型的时间相关类:GregorianCalendar, java.util.Date, java.sql.Date, Timestamp, DateTimeStamp

Calendar c = jdt.convertToCalendar();
jdt.convertToGregorianCalendar();
jdt.convertTo(GregorianCalendar.class);  // generic way of conversion
jdt = new JDateTime(gregCalInstance);    // create from GregorianCalendar
jdt.loadFrom(gregCalInstance);       // load time data from GregorianCalendar
jdt.storeTo(gregCalInstance);        // store time data to GregorianCalendar

字符串转换

时间对象和字符串之间的转换,也是很重要的一部分。JDateTime支持两种转换方式:①调用JDateTime对象的内部方法;②使用外部的格式化类,来格式化输出JDateTime对象。

对于JDateTime提供的所有转换方法来说,都是通过实现JdtFormatter接口来实现。
下面是时间格式化输出的字符串模板:

PatternParsing?Value
YYYYyesyear
MMyesmonth
DDyesday of month
Dday of week
MMLmonth name long
MMSmonth name short
DLday of week name long
DSday of week name short
hhyeshour
mmyesminute
ssyesseconds
mssyesmilliseconds
DDDday of year
WWweek of year
WWWweek of year with 'W' prefix
Wweek of month
Eera (AD or BC)
TZLtime zone name long
TZStime zone name short

如果要输出的文本和字符串模板冲突,可以使用单引号来禁止解析。
代码样例:

JDateTime jdt = new JDateTime(1975, 1, 1);
jdt.toString();                     // "1975-01-01 00:00:00.000"
jdt.toString("YYYY.MM.DD");         // "1975.01.01"
jdt.toString("MM: MML (MMS)");      // "01: January (Jan)"
jdt.toString("DD is D: DL (DS)");   // "01 is 3: Wednesday (Wed)"
JDateTime jdt = new JDateTime(1968, 9, 30);
jdt.toString("'''' is a sign, W is a week number and 'W' is a letter");
// "' is a sign, 5 is a week number and W is a letter"

jdt.parse("2003-11-24 23:18:38.173");
jdt.parse("2003-11-23");                // 2003-11-23 00:00:00.000
jdt.parse("01.01.1975", "DD.MM.YYYY");  // 1975-01-01
jdt.parse("2001-01-31", "YYYY-MM-***"); // 2001-01-01, since day is not parsed

JDateTime jdt = new JDateTime();
JdtFormatter fmt = new DefaultFormatter();
fmt.convert(jdt, "YYYY-MM.DD");         // external conversion

JdtFormat format = new JdtFormat(new DefaultFormatter(), "YYYY+DD+MM");
jdt.toString(format);
format.convert(jdt);

DateFormat df = new SimpleDateFormat();
df.format(jdt.convertToDate());         // date formatter

时区

JDateTime支持时区的设置,设置时区时,JDateTime对象存储的时间也会进行相应修改.

JDateTime jdt = new JDateTime(); //假如是上午8点
jdt.setTimeZone(TimeZone.getTimeZone("Japan"));
System.out.println(jdt); //同样也是上午8点

如果想在修改时区时,不修改时间,可以使用changeTimeZone方法,这样北京的上午8点,就对应为东京的上午9点。

版权声明

本站文章、图片、视频等(除转载外),均采用知识共享署名 4.0 国际许可协议(CC BY-NC-SA 4.0),转载请注明出处、非商业性使用、并且以相同协议共享。

© 空空博客,本文链接:https://www.yeetrack.com/?p=1226