您的位置:首页 > 其它

joda-time介绍

2015-10-23 10:28 337 查看
一、Joda简介

目前Joda项目包括:

Joda-Time - Basic types for Date and Time

Joda-Money - Basic types for Money

Joda-Beans - Next generation JavaBeans

Joda-Convert - String to Object conversion

Joda-Collect - Additional collection data structures

Joda-Primitives - Primitive collections

这里简要介绍下Joda-Time。

Joda-Time令时间和日期值变得易于管理、操作和理解。并且 Joda 与 JDK 的互操作性也方便程序使用。目前Joda Time 已经纳入 JDK 8 的官方API了。

二、Maven库坐标

<dependency>

<groupId>joda-time</groupId>

<artifactId>joda-time</artifactId>

<version>2.7</version>

</dependency>

三、Joda-Time的关键日期/时间概念

1. 不可变性(Immutability)

我在本文讨论的Joda-Time类具有不可变性,因此它们的实例无法被修改。(不可变类的一个优点就是它们是线程安全的)。我将向您展示的用于处理日期计算的 API方法全部返回一个对应Joda-Time类的新实例,同时保持原始实例不变。当您通过一个API方法操作Joda-Time类时,您必须捕捉该方法的返回值,因为您正在处理的实例不能被修改。您可能对这种模式很熟悉;比如,这正是 java.lang.String的各种操作方法的工作方式。

2. 瞬间性(Instant)

Instant表示时间上的某个精确的时刻,使用从epoch(1970-01-01 00:00:00 UTC)开始计算的毫秒表示。这一定义与JDK相同,这就是为什么任何Joda-Time Instant子类都可以与JDK Date和Calendar类兼容的原因。

相关类比如DateTime、DateMidnight等。

3. 局部性(Partial)

一个局部时间,正如我将在本文中将其称为局部时间片段一样,它指的是时间的一部分片段。局部时间片段指的是在时间上可以来回 “移动” 的一个时刻,这样它便可以应用于多个实例。

相关类比如:LocalDate、LocalTime等。

4. 年表(Chronology)

年表是一种日历系统、一种计算时间的特殊方式,并且是一种在其中执行日历算法的框架。Joda-Time支持8种年表,每一种都可以作为特定日历系统的计算引擎。

ISO(默认)

Buddhist

Coptic

Ethiopic

Gregorian-Julian cutover

Gregorian

Islamic

Julian

相关类比如ISOChronology、GregorianChronology等。

5. 时区(TimeZone)

时区是值一个相对于英国格林威治的地理位置,用于计算时间。任何严格的时间计算都必须涉及时区(或相对于 GMT)。

DateTimeZone 是Joda-Time库用于封装位置概念的类。许多日期和时间计算都可以在不涉及时区的情况下完成,但是仍然需要了解DateTimeZone 如何影响Joda-Time的操作。默认时间,即从运行代码的机器的系统时钟检索到的时间,在大部分情况下被使用。

四、DateTime类

1. 创建对象

DateTime类提供多种构造函数创建对象,也包括使用jdk对象作构造函数的传入参数,比如DateTime类可以传入以下对象来构造:

java.util.Date - a JDK instant

java.util.Calendar - a JDK canlendar

String - in ISO8601 format

Long - in milliseconds

any Joda-Time date-time class

例子:

java.util.Date jDate = new Date();

DateTime dt = new DateTime(jDate);

2. 属性&方法

DateTime dt = new DateTime();

int month = dt.getMonthOfYear(); // 月,1月值为1,12月值为12

int year = dt.getYear(); // 年

String monthName = dt.monthOfYear().getAsText(); // 四月

String frenchShortName = dt.monthOfYear().getAsShortText(Locale.ENGLISH); // Apr

boolean isLeapYear = dt.year().isLeap(); // false

// 值变后就会产生新对象(不可变性)

DateTime yearK2 = dt.withYear(2000).plusWeeks(2);

DateTime rounded = dt.dayOfMonth().roundFloorCopy();

五、局部日期时间

当地理位置(即时区)变得不重要时,存储日期可使用LocalDate,存储时间可使用LocalTime。

LocalDate localDate = new LocalDate(2009, 9, 6);// September 6, 2009

LocalTime localTime = new LocalTime(13, 30, 26, 0);// 1:30:26PM

六、年表&时区

Joda-Time采用可插拔方式的年表系统,相比之下,JDK使用子类的方式,比如GregorianCalendar。看例子:

Chronology coptic = CopticChronology.getInstance();

DateTimeZone zone = DateTimeZone.forID("Asia/Tokyo");

Chronology gregorianJuian = GJChronolygy.getInstance(zone);

七、间隔&区间&跨度

Interval: 它包含了「开始时间」和「结束时间」信息,包括各自的时区。所以可以根据Interval对象得到「开始时间」和「结束时间」这两个信息。

Duration: 它没有任何「开始时间」和「结束时间」的概念,只是保存了一个具体的时间间隔,是一个以毫秒为单元的整数。

Period : 它和「Duration」差不多意思,也是没有包含「开始时间」和「结束时间」的信息,但是它和「Duration」不同的是,它所指的时间间隔不是以毫秒为单元,而是年、月、天、小时、分、秒、毫秒为相对单元。

先看例子:

DateTime start = new DateTime(2011,12,2,15,33); //开始时间

DateTime end = new DateTime(2013,3,1,12,34); //结束时间

Interval interval = new Interval(start, end);

Duration duration =new Duration(start, end);

Period period =interval.toPeriod();

boolean between = interval.contains(new DateTime(2013, 2, 1, 12, 34));

long millSeconds = duration.getMillis();

long millSeconds1 = period.getMillis();

结果:

between = true

millSeconds = 39301260000

millSeconds1 = 0

前两个值好理解,但duration和period调用getMillis()会出现不同结果就不好理解了。这里解释下:duration.getMillis返回的是绝对相差毫秒数;而period.getMillis返回0,是因为「开始时间」和「结束时间」间隔的相对时间是:1年2个月3个星期5天21个小时1分钟。

八、格式化

要格式化一个Joda-Time对象,调用它的toString()方法即可。如果您愿意的话,传递一个标准的ISO-8601或一个JDK兼容的控制字符串,以告诉JDK如何执行格式化。不需要创建单独的 SimpleDateFormat对象(但是 Joda 的确为那些喜欢自找麻烦的人提供了一个 DateTimeFormatter 类)。看例子:

1.传递SimpleDateFormat字符串

DateTime dateTime = new DateTime();

dateTime.toString("yyyy/MM/dd hh:mm:ss.SSSa");
// 2015/04/21 01:08:57.343下午

dateTime.toString("dd-MM-yyyy HH:mm:ss"); // 21-04-2015 13:08:57

dateTime.toString("EEEE dd MMMM, yyyy HH:mm:ssa");
// 星期二 21 四月, 2015 13:08:57下午

dateTime.toString("MM/dd/yyyy HH:mm ZZZZ");
// 04/21/2015 13:08 Asia/Shanghai

dateTime.toString("MM/dd/yyyy HH:mm Z"); // 04/21/2015 13:08 +0800

2. 使用ISO-8601

DateTime dateTime = new DateTime();

dateTime.toString(ISODateTimeFormat.basicDateTime()); // 20150421T121247.421+0800

dateTime.toString(ISODateTimeFormat.basicDateTimeNoMillis()); // 20150421T121247+0800

dateTime.toString(ISODateTimeFormat.basicOrdinalDateTime()); // 2015111T121247.421+0800

dateTime.toString(ISODateTimeFormat.basicWeekDateTime()); // 2015W172T121247.421+0800
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: