Java8新特性Date和Time介绍



Java8新特性Date和Time介绍。

为什么我们需要一套新的Date和Time库
Java开发者长期以来一个棘手的问题就是Date和Time类库,Java SE这套类库一直存在问题。
例如java.util.Data和SimpleDateFormatter不是线程安全的。
Date和Time存在一些非常悲略的设计,比如java.util.Date年份始点是1900,月份起始点是1,日期起始点是0。
Oracle基于JSR310规范开发了一套新的实现,Java SE下的包名是java.time
核心思想
新API有3个核心思想:
1、值不可变类。旧的API的缺点就是非线程安全的,究其根本原因就在与值变化,为了解决这个问题,新的API才有值不可变的特性,从而达到了线程安全的目的。
2、领域设计。
3、分离年代。
LocalDate和LocalTime
首先我们要介绍的新API是LocalDate和LocalTime。他们就像我们日常生活中的日期和时间一样,比如放在左面上的闹钟或者是挂在墙上的时钟。有一个组件叫做LocalDateTime,它综合了LocalDate和LocalTime的功能。
构造对象
我们看看从不同方式所构造的对象实例
1
2
3
4
5
6
LocalDateTime timePoint = LocalDateTime.now(
); // 当前的日期和时间。
LocalDate.of(2012, Month.DECEMBER, 12); // 基于数值构造。
LocalDate.ofEpochDay(150); // 1970中间。
LocalTime.of(17, 18); // 今天我坐火车回家。
LocalTime.parse(“10:15:30″); // 从字符串构造。
从对象中获取时间数值
1
2
3
4
LocalDate theDate = timePoint.toLocalDate();
Month month = timePoint.getMonth();
int day = timePoint.getDayOfMonth();
timePoint.getSecond();
由于值不可变的原因,需要使用with方法返回新的对象,而不是使用set方法去变更原来的时间。
1
2
3
4
5
6
7
8
// Set the value, returning a new object
LocalDateTime thePast = timePoint.withDayOfMonth(
10).withYear(2010);

/* You can use direct manipulation methods,
or pass a value and field pair */
LocalDateTime yetAnother = thePast.plusWeeks(
3).plus(3, ChronoUnit.WEEKS);
新的API有类似调节起的概念,可以得到一些逻辑概念上的日期。
1
2
3
4
5
6
7
8
import static java.time.temporal.TemporalAdjusters.*;

LocalDateTime timePoint = …
foo = timePoint.with(lastDayOfMonth());
bar = timePoint.with(previousOrSame(ChronoUnit.WEDNESDAY));

// Using value classes as adjusters
timePoint.with(LocalTime.now());
截断
新的API允许你从完整的日期和时间对象中进行类型截断。使用truncatedTo可以达到截断的目的:
1
LocalTime truncatedTime = time.truncatedTo(ChronoUnit.SECONDS);
时区
时区ID:
1
2
3
4
// 你可以指定时区的ID来构造ZonedDateTime对象。
ZoneId id = ZoneId.of(“Europe/Paris”);
ZonedDateTime zoned = ZonedDateTime.of(dateTime, id);
assertEquals(id, ZoneId.from(zoned));
时区调整:
1
ZoneOffset offset = ZoneOffset.of(“+2:00″);
TimeZone对象
1
ZonedDateTime.parse(“2007-12-03T10:15:30+01:00[Europe/Paris]“);
OffsetDateTime 是一个具有时间和日期的一个可分离的对象,通常被使用在数据库的持久化中,允许你分析有用不同时区的时间日志格式。
OffsetTime 是一个具备时间的一个可分离的对象。
1
2
3
4
5
6
7
8
9
10
11
OffsetTime time = OffsetTime.now();
// changes offset, while keeping the same point on the timeline
OffsetTime sameTimeDifferentOffset = time.withOffsetSameInstant(
offset);
// changes the offset, and updates the point on the timeline
OffsetTime changeTimeWithNewOffset = time.withOffsetSameLocal(
offset);
// Can also create new object with altered fields as before
changeTimeWithNewOffset
.withHour(3)
.plusSeconds(2);
周期
Period 代表一个周期性时间的值,例如“3个月又1天”,表示一个和timeline的距离。
1
2
3
4
5
6
7
8
// 三年, 两月, 一天
Period period = Period.of(3, 2, 1);

// You can modify the values of dates using periods
LocalDate newDate = oldDate.plus(period);
ZonedDateTime newDateTime = oldDateTime.minus(period);
// Components of a Period are represented by ChronoUnit values
assertEquals(1, period.get(ChronoUnit.DAYS));
区间
1
2
3
// 一个持续3毫秒和5纳秒的时间。
Duration duration = Duration.ofSeconds(3, 5);
Duration oneDay = Duration.between(today, yesterday);
年代
1
2
3
4
Chronology:
ChronoLocalDate
ChronoLocalDateTime
ChronoZonedDateTime
JDBC和Java SE 8
ANSI SQL Java SE 8
DATE LocalDate
TIME LocalTime
TIMESTAMP LocalDateTime
TIME WITH TIMEZONE OffsetTime
TIMESTAMP WITH TIMEZONE OffsetDateTime

本文来源:逍遥冲