快捷搜索:  as  test  1111  test aNd 8=8  test++aNd+8=8  as++aNd+8=8  as aNd 8=8

太阳集团娱乐网址首页:JSR 310:新Java 日期时间 API



对 Java 6 日期/光阴 API 的改进

JSR 310 日期/光阴 API 试图经由过程供给更好的机能和易用性改进 Java 确当前日期/光阴 API。例如,Java Calendar 类将日期同时存储为与标准纪元之间的偏移量(以毫秒为单位)以及一组日历字段(例如,礼拜几、几号以及月份)。此双精度表示导致在意外的光阴从新谋略日历字太阳集团娱乐网址首页段,从而孕育发生弗成猜测的机能特征。与此比拟,JSR 310 类仅将日期/光阴表示存储为与 Date 和 Calendar 所应用的同一标准纪元之间的偏移量(以毫秒为单位);仅当必要时才管帐算日期等日历字段,并且不会应用这些日历字段进行内部日期表示。

JSR 310 还对当前 Java 日期/光阴模型进行了改进。Java 6 API 不包孕表示本地光阴(不具有关联时区的光阴)、持续光阴或光阴距离的类。这迫使法度榜样员应用令人利诱的设计做法,例如应用 int 表示持续光阴。JSR 310 包孕表示上述各个观点的类,从而可以进行更为明确的法度榜样设计。

着末,JSR 310 API 经由过程应用弗成改变的类努力实现线程安然。Java 当前的日期/光阴类 Date 和 Calendar 都是可改变的,因而都不是线程安然的。

JSR 310 日期/光阴太阳集团娱乐网址首页观点

JSR 310 API 使用了从多个第三方 Java 日期/光阴 API 中得到的履历。JSR 310 主要基于 Joda Time API;其他影响身分包括 ICU、Time and Money 和 Calendar Date。JSR 3太阳集团娱乐网址首页10 的 API 是环抱 Joda Time 中应用的相同 5 个基今天期/光阴观点构建的:

离散的光阴线

瞬间

不完全光阴

持续光阴

时段

光阴距离

离散的光阴线

像 Joda Time 一样,JSR 310 应用离散化的光阴线:光阴被建模为由小的固定持续光阴分隔的继续的瞬间序列。JSR 310 的离散光阴线具有纳秒分辨率,是以可以表示光阴“2008 年 1 月 1 日午夜后 1 纳秒”,但不能表示光阴“2008 年 1 月 1 日午夜后 1 皮秒”。该光阴线上的每个离散纳秒都被视为一个瞬间,如下所示。

瞬间

瞬间是离散化光阴线上的特定点。一个瞬间示例是“天下标定光阴 2008 年 1 月 7 日 23:00:00.0”。同样可以将瞬间定义为与标准纪元之间的偏移量(以纳秒为单位),例如“天下标定光阴 1970 年 1 月 1 日之后 20,000,000 纳秒”。这两个阐明都定义了离散光阴线上的单个独一点。瞬间不合于不完全光阴,后者定义了光阴线上的一组时候,而不是一个独一的时候。

JSR 310 API 供给了多个表示瞬间的类:Instant、OffsetDateTime 和 ZonedDateTime,所有这些类都实现了 ReadableInstant 接口。OffsetDateTime 类表示日期、逐日光阴以及与天下标定光阴 (coordinated universal time, UTC)之间的偏移量(如 +1:00)。类似的 ZonedDateTime 类包孕时区 ID(如 America/New_York)而不是偏移量。给定的时区可能应用多个不合的偏移量,详细取决于一年中的光阴;例如,America/New_York 时区的偏移量在夏令时为 -4:00,在其他光阴为 -5:00。是以,当必须斟酌特定于区域设置的光阴规则(如夏令时)时,应该应用 ZonedDateTime 类。

ZonedDateTime 类供给了几种类其余用于创建、造访和改动瞬间的措施。要创建 ZonedDateTime 的新实例以表示谋略机的默认时区中确当前系统光阴,可以应用 Clock.currentZonedDateTime() 工厂措施,如下面的示例所示。

Clock systemClock = Clock.system();

ZonedDateTime currentTime = systemClock.currentZonedDateTime();

要创建一个 ZonedDateTime 实例以表示特定的、预先确定的日期,可以应用多个 ZonedDateTime.dateTime 工厂措施之一。下面的示例演示了若何创建一个 ZonedDateTime 以表示谋略机的默认时区中的 2000 年 1 月 1 日午夜。

Clock systemClock = Clock.system();

TimeZone defaultTimeZone = systemClock.timeZone();

int year = 2000;

int month = 1;

int day = 1;

int hour太阳集团娱乐网址首页 = 0;

int minute = 0;

ZonedDateTime theDate = ZonedDateTime.dateTime(year,

month, day, hour, minute, defaultTimeZone);

OffsetDateTime 实例的创建要领与 ZonedDateTime 实例类似,差别在于传入 OffsetDateTime.dateTime 工厂措施的是 ZoneOffset 而不是 TimeZone。要得到 ZoneOffset 的实例,可以应用静态 ZoneOffset.zoneOffset(int hours) 措施,此中 hours 是与 UTC 之间的偏移量(以小时为单位)。

不完全光阴

不完全光阴是这样一种日期或光阴表示,即它不够以指准光阴线上的特定独一点。例如,“6 月 7 日”是一个不完全光阴,由于它指定月份和日期,但未指定年份或逐日光阴。是以,上述不完全光阴不够以标识光阴线上的独一点。由于不完全光阴不标识特定的光阴,以是无法将其表示为与标准纪元之间的偏移量(以纳秒为单位)。它们的定义一定是基于字段的,并且应用年、月、日和逐日光阴等日历字段。

可以根据不完全光阴所定义的日历字段集对其进行分类。例如,表示年度假期的不完全光阴可能包孕月和日字段,而表示市廛开业光阴的不完全光阴可能包孕时和分字段。JSR 310 为常用的不完全光阴供给了类,例如 MonthDay(前面提到的“假期”不完全光阴)、LocalDate(不带光阴或时区的日期)以及 LocalTime(不带时区的光阴)。要创建 MonthDay 或其他某个现成的不完全光阴类的实例,可以应用所供给的静态工厂措施之一。下面的示例特定于 MonthDay,但可以轻松地针对其他某个不完全光阴类改写该示例。

//Create a MonthDay representing December 25 (Christmas)

int theMonth = 12;

int theDay = 25;

MonthDay christmas = MonthDay.monthDay(theMonth, theDay);

持续光阴

持续光阴表示一段已经流逝的光阴,并且定义到纳秒级;例如“100,000 纳秒”是一个持续光阴。持续光阴有点类似于时段,后者也定义了一段已经流逝的光阴;然则,与时段不合,持续光阴表示已流逝纳秒的正确数目。

可以将持续光阴添加到瞬间以返回一个新的瞬间,该瞬间与原始瞬间之间偏移持续光阴中的纳秒数。例如,假如持续光阴“86,400,000,000,000 纳秒”(24 小时)被添加到瞬间“天下标定光阴 2008 年 3 月 1 日午夜”,则孕育发生的瞬间为“天下标定光阴 2008 年 3 月 2 日午夜”。

可以用以下两种要领创建持续光阴:经由过程为持续光阴供给秒、毫秒或纳秒光阴跨度,或者经由过程供给肇端瞬间和停止瞬间。第一种措施得当于创建具有预先确定的长度的持续光阴:

System.out.println("Enter a duration length in hours:");

Scanner s = new Scanner(System.in);

int durationSeconds = 3600 * s.nextInt();

Duration d = Duration.duration(durationSeconds);

作为一种替代要领,您可能盼望确定两个预先确定的瞬间之间的持续光阴。在这种环境下,静态的 Duration.durationBetween(ReadableInstant startInclusive, ReadableInstant endExclusive) 工厂措施很有用。

Clock systemClock = Clock.system();

ZonedDateTime instant1 = systemClock.currentZonedDateTime();

try{Thread.sleep(1000)} //Use up some time

catch(InterruptedException e){System.out.println("Error")}

ZonedDateTime instant2 = systemClock.currentZonedDateTime();

Duration d = Duration.durationBetween(instant1, instant2);

时段

像持续光阴一样,时段表示一段已经消逝的光阴。时段的示例有“4 年零 8 天”和“1 小时”。如这些示例所示,时段是应用日历字段(年、日、小时等)定义的,而不是经由过程确切的纳秒数确定的。

首先,时段和持续光阴可能看起来像是表达同一观点的不合要领;然则,正如下面的瞬间/时段加法示例所演示的那样,无法将给定的时段转换为确切的纳秒数。瞬间/时段加法将时段的每个日历字段的值添加到瞬间的响应字段。瞬间/持续光阴加法与此相反,该加法将持续光阴的长度(以纳秒为单位)添加到瞬间。乍看起来,向给定的瞬间添加 86,400,000,000,000 纳秒(24 小时)持续光阴彷佛应该与添加“1 天”的时段孕育发生相同的结果,但环境并非老是如斯,缘故原由这天历字段“日”不具有固定的纳秒长度。大年夜多半日都是 24 小时长,但因为存在夏令时,是以某些日要长一些或短一些。向瞬间添加 24 小时持续光阴老是将该瞬间正好推进 24 小时,而添加一个 1 天的时段老是将日推进 1,同时使逐日光阴维持不变。

例如,假如将时段“1 日”添加到瞬间“美国东部光阴 2008 年 3 月 9 日午夜”,则获得的基于字段的加法将孕育发生“美国东部光阴 2008 年 3 月 10 日午夜”。然则,假如将一个 24 小时的持续光阴添加到瞬间“美国东部光阴 2008 年 3 月 9 日午夜”,则结果为“美国东部光阴 2008 年 3 月 10 日 01:00:00.0”。两者之间的区别源于:夏令时开始于美国东部光阴 2008 年 3 月 9 日 02:00:00;是以,该日只有 23 小时长。

JSR 310 经由过程多个类供给了时段功能,此中最为紧张的类是 Period、Periods.Builder 以及 Periods.Builder 的子类:Periods.SecondsBuilder、Periods.MinutesBuilder(它是 SecondsBuilder 的子类)等(不停到 Periods.YearsBuilder)。

要创建 Period 的实例,您必须首先应用静态 Periods.periodBuilder() 措施获取 Periods.Builder 的实例。此措施返回一个 Periods.YearsBuilder 工具,这是 Periods.Builder 的一个间接子类。Periods.YearsBuilder 类供给了一个措施 years(int numYears),该措施将 numYears 年添加到所天生的时段。应用 YearsBuilder 的直接和间接超类(MonthsBuilder、DaysBuilder、HoursBuilder、MinutesBuilder 和 SecondsBuilder)可以将其另日历字段添加到该时段。例如,MinutesBuilder.minutes(int numMinutes) 向所天生的时段添加 numMinutes 分钟。上述所有措施都返回 this,因而,只需一条语句就可以天生具有多个日历字段的时段。请留意,经由过程将一个负整数通报到适当的 builder 措施中,可以对时段履行减法。在将所有必要的字段添加到该时段之后,将调用 Periods.PeriodBuilder.build() 太阳集团娱乐网址首页措施以返回 Period 的完备实例。

//Build a period representing "8 years, 3 months."

Period thePeriod =

Periods.periodBuilder().years(8).months(3).build();

光阴距离

光阴距离表示光阴线上的两个瞬间之间的一段光阴。是以,“天下标定光阴 2007 年 1 月 1 日(包括)到天下标定光阴 2008 年 1 月 1 日(不包括)”是一个光阴距离。光阴距离可以包括或不包括肇端瞬间和停止瞬间。

JSR 310 供给了 InstantInterval 类来表示光阴距离。要创建 InstantInterval 的实例,可以应用多个工厂措施之一:

//Create some intervals.

ZonedDateTime time1 = systemClock.currentZonedDateTime();

try{Thread.sleep(1000)} //Use up some time

catch(InterruptedException e){System.out.println("Error")}

ZonedDateTime time2 = systemClock.currentZonedDateTime();

//Create an interval with inclusive start and exclusive end.

InstantInterval interval1 = InstantInterval.intervalBetween(

time1.toInstant(), time2.toInstant());

//Create an interval with exclusive start and inclusive end.

boolean startInclusive = false; boolean endInclusive = true;

InstantInterval interval2 = InstantInterval.intervalBetween(

time1.toInstant(), startInclusive,

time2.toInstant(), endInclusive);

应用 JSR 310 日期/光阴类

前面的部分先容了 5 个基础 JSR 310 日期/光阴观点,并且阐明若何实例化表示这些观点的类。本部分演示一些可以应用 JSR 310 API 进行的日历谋略。

对了进行演示,假设您正在开拓的法度榜样采纳多个在不合光阴发生并且按照特准光阴距离重复发生的事故作为输入。该法度榜样输出所有同时发生两个或更多个事故的光阴。您可以应用一个 ZonedDateTime 和一个 Duration 来表示在颠末固定长度的光阴之后从新发生的瞬间事故;要天生该事故的下一个实例,可以向表示上一个实例的 ZonedDateTime 添加 Duration:

//ZonedDateTime firstTime is the time the event first occurs

//Duration repeatTime is the duration after which event recurs

//TimeZone defaultZone is your computer's default time zone

ZonedDateTime secondTime = ZonedDateTime.dateTime(

firstTime.toInstant().plus(repeatTime), defaultZone);

假如您具有一个在特定命量的年、月或日之后重复发生的事故,则可以经由过程向表示上一个实例的 ZonedDateTime 添加一个 Period 来天生下一个实例:

//ZonedDateTime firstTime is the time the event first occurs

//Period repeatPeriod is the period after which event recurs

ZonedDateTime secondTime = firstTime.plus(repeatPeriod);

要测试两个瞬间事故是否同时发生,可以应用 ZonedDateTime.equals(Object other) 措施:

//time1 and time2 are ZonedDateTimes representing events

if (time1.equals(time2)){

System.out.println("The two events occur simultaneously.");

}

假如您必要表示一个非瞬间事故,则应用 ZonedDateTime 并非最佳选择。不完全光阴加倍得当于表示非瞬间事故(如年假)。要确定一个由 ZonedDateTime 表示的事故和一个由不完全光阴(例如,MonthDay)表示的事故是否同时发生,可以应用 MonthDay.matchesDate(LocalDate date) 措施。假如 LocalDate(它是一个不带逐日光阴的日期)中的月和日字段与 MonthDay 中的月和日字段匹配,则此措施返回 true。

//Monthday christmas is a partial representing December 25.

//ZonedDateTime time1 represents an instantaneous event

if (christmas.matchesDate(time1.localDate())){

System.out.println("The event occurs on Christmas.");

}

着末,经由过程 InstantInterval 可以最佳地表示按照特准光阴跨度发生的事故。要测试一个 InstantInterval 是否与一个 ZonedDateTime 重叠,可以应用 InstantInterval.contains(InstantProvider instant) 措施。(InstantProvider 是一个由三个 JSR 310 瞬间类实现的接口。)

//InstantInterval event1 is an event that occurs over a timespan

//ZonedDateTime event2 is an instantaneous event

if (event1.contains(event2)){

System.out.println("Event 2 occurs during event 1.");

}

停止语

本文演示了 JSR 310 的一些功能,JSR 310 是为 Java 7 发起的一个新的 Java 日期/光阴 API。详细说来,本文演示了表示下列 5 个 JSR 310 日期/光阴观点的类的用法:瞬间、不完全光阴、持续光阴、时段和光阴距离。JSR 310 中还有其他许多功能未在本文中予以先容,如高档日期/光阴匹配功能。此外,由于本文主要基于当前 JSR 310 API 的快照,以是在本文宣布之后可能添加其他功能。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

您可能还会对下面的文章感兴趣: