Java 8中的时区操作被很大程度上简化了,新的时区类 java.time.ZoneId 是原有的 java.util.TimeZone 类的替代品。
ZoneId对象可以通过 ZoneId.of() 方法创建,也可以通过 ZoneId.systemDefault() 获取系统默认时区:
ZoneId shanghaiZoneId = ZoneId.of("Asia/Shanghai");
ZoneId systemZoneId = ZoneId.systemDefault();of() 方法接收一个“区域/城市”的字符串作为参数,你可以通过 getAvailableZoneIds() 方法获取所有合法的“区域/城市”字符串:
Set<String> zoneIds = ZoneId.getAvailableZoneIds();对于老的时区类 TimeZone,Java 8也提供了转化方法:
ZoneId oldToNewZoneId = TimeZone.getDefault().toZoneId();有了 ZoneId,我们就可以将一个 LocalDate、LocalTime 或 LocalDateTime 对象转化为 ZonedDateTime 对象:
LocalDateTime localDateTime = LocalDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, shanghaiZoneId);ZonedDateTime 对象由两部分构成,LocalDateTime 和 ZoneId,其中 2018-03-03T15:26:56.147 部分为 LocalDateTime,+08:00[Asia/Shanghai] 部分为ZoneId。
另一种表示时区的方式是使用 ZoneOffset,它是以当前时间和 世界标准时间(UTC)/格林威治时间(GMT) 的偏差来计算,例如:
ZoneOffset zoneOffset = ZoneOffset.of("+09:00");
LocalDateTime localDateTime = LocalDateTime.now();
OffsetDateTime offsetDateTime = OffsetDateTime.of(localDateTime, zoneOffset);Instant类在Java日期与时间功能中,表示了时间线上一个确切的点,定义为距离初始时间的时间差(初始时间为GMT 1970年1月1日00:00)经测量一天有86400秒,从初始时间开始不断向前移动。
创建一个Instant实例
你可以通过Instant类的工厂方法创建一个Instant实例,例如你可以调用instant.now()来创建一个确切的表达当前时间的Instant对象:
Instant now = Instant.now();另外也有一些其它方法能创建Instant,具体请查阅Java官方文档。
访问Instant的时间
一个Instant对象里有两个域:距离初始时间的秒钟数、在当前一秒内的第几纳秒,他们的组合表达了当前时间点。你可以通过以下两个方法得到它们的值:
long seconds = getEpochSecond()
int nanos = getNano()Instant的计算
Instant类有一些方法,可以用于获得另一Instant的值,例如:
plusSeconds()plusMillis()plusNanos()minusSeconds()minusMillis()minusNanos()
我下面将向你展示两个例子,来说明这些方法如何使用:
Instant now = Instant.now();
Instant later = now.plusSeconds(3);
Instant earlier = now.minusSeconds(3);第一行获得了一个Instant对象,表示当前时间。第二行创建了一个Instant表示三秒后,第三行创建了一个Instant表示三秒前。
seconds 表示从
1970-01-01 00:00:00开始到现在的秒数,nanos 表示纳秒部分(nanos的值不会超过999,999,999)
Clock类提供了访问当前日期和时间的方法,Clock是时区敏感的,可以用来取代 System.currentTimeMillis() 来获取当前的微秒数。
某一个特定的时间点也可以使用Instant类来表示,Instant 类也可以用来创建老的 java.util.Date 对象。
Clock clock = Clock.systemDefaultZone();
long millis = clock.millis();
Instant instant = clock.instant();
Date legacyDate = Date.from(instant); // legacy java.util.Date LocalDate类是Java 8中日期时间功能里表示一个本地日期的类,它的日期是无时区属性的。 可以用来表示生日、节假日期等等。这个类用于表示一个确切的日期,而不是这个日期所在的时间(如java.util.Date中的2000.01.01表示的实际是这一天的00:00这个瞬间)。
LocalDate类位于java.time包下,人名叫java.time.LocalDate,创建出来的实例也是不可变对象,所以涉及它的计算方法将返回一个新的LocalDate。
创建一个LocalDate实例
我们有多种方式可以创建出 LocalDate 实例。第一种方法是使用 now() 方法获得值为今天当日的 LocalDate 对象:
LocalDate localDate = LocalDate.now();另一种方法是使用年月日信息构造出LocalDate对象:
LocalDate localDate2 = LocalDate.of(2018, 3, 3);LocalDate 的 of() 方法创建出一个指定年月日的日期,并且没有时区信息。
访问日期信息
可以用如下方法访问LocalDate中的日期信息:
int year = localDate.getYear();
Month month = localDate.getMonth();
int dayOfMonth = localDate.getDayOfMonth();
int dayOfYear = localDate.getDayOfYear();
DayOfWeek dayOfWeek = localDate.getDayOfWeek();可以注意到getMonth()与getDayOfWeek()方法返回了一个枚举类型代替一个int。你可以通过枚举类型中的getValue()来获得信息。
LocalDate计算
你可以进行一堆简单的日期计算,只要使用如下的方法:
plusDays()plusWeeks()plusMonths()plusYears()minusDays()minusWeeks()minusMonths()minusYears()
以下举几个使用的例子来帮助理解使用:
LocalDate d = LocalDate.of(2018, 3, 5);
LocalDate d1 = localDate.plusYears(3);
LocalDate d2 = localDate.minusYears(3);- 第一行创建出一个新的LocalDate对象d,表示2018.3.5。
- 第二行创建了值等于d日期3年后的LocalDate对象,第三行也是一样,只是值改为d日期的三年前。
LocalTime类是Java 8中日期时间功能里表示一整天中某个时间点的类,它的时间是无时区属性的(早上10点等等)。比如你需要描述学校几点开学,这个时间不涉及在什么城市,这个描述是对任何国家城市都适用的,此时使用无时区的LocalTime就足够了。 LocalTime类的对象也是不可变的,所以计算方法会返回一个新的LocalTime实例。
创建一个LocatTime实例
有多种方式可以新建LocalTime实例。比如使用当前时间作为值新建对象:
LocalTime localTime = LocalTime.now();另一种方式是使用指定的时分秒和纳秒来新建对象:
LocalTime localTime2 = LocalTime.of(21, 30, 59, 11001);也有另一种版本的 of() 方法只需要小时分钟两项,或时分秒三项值作为参数。
访问LocalTime对象的时间
你可以通过这些方法访问其时、分、秒、纳秒:
getHour()getMinute()getSecond()getNano()
LocalTime的计算
LocalTime类包含一系列方法,能帮你完成时间计算:
plusHours()plusMinutes()plusSeconds()plusNanos()minusHours()minusMinutes()minusSeconds()minusNanos()
以下举一个例子:
LocalTime localTime2 = LocalTime.of(21, 30, 59, 11001);
LocalTime localTimeLater = localTime.plusHours(3);
LocalTime localTimeEarlier = localTime.minusHours(3);- 第一行新建一个LocalTime实例,表示21:30:50的第11001纳秒。
- 第二行新建了一个LocalTime实例表示这个时间的三小时后,第三行表示三小时前。
- LocalTime类是Java 8中日期时间功能里表示一整天中某个时间点的类,它的时间是无时区属性的(早上10点等等)。比如你需要描述学校几点开学,这个时间不涉及在什么城市,这个描述是对任何国家城市都适用的,此时使用无时区的LocalTime就足够了。
LocalTime类的对象也是不可变的,所以计算方法会返回一个新的LocalTime实例。
LocalDateTime类是Java 8中日期时间功能里,用于表示当地的日期与时间的类,它的值是无时区属性的。你可以将其视为Java 8中LocalDate与LocalTime两个类的结合。
LocalDateTime类的值是不可变的,所以其计算方法会返回一个新的LocalDateTime实例。
创建一个LocatDateTime实例
可以通过LocalDateTime的静态工厂方法来创建LocalDateTime实例。以下举例使用 now() 方法创建:
LocalDateTime localDateTime = LocalDateTime.now();另一种方式是使用指定的年月日、时分秒、纳秒来新建对象:
LocalDateTime localDateTime2 = LocalDateTime.of(2018, 11, 26, 13, 55, 36, 123);访问LocalDateTime对象的时间
你可以通过这些方法访问其日期时间:
getYear()getMonth()getDayOfMonth()getDayOfWeek()getDayOfYear()getHour()getMinute()getSecond()getNano()
这些方法中有一些返回int有一些返回枚举类型,你可以通过枚举类型中的 getValue() 方法来获得int值。
LocalDateTime的计算
LocalDateTime 类包含一系列方法,能帮你完成时间计算:
plusYears()plusMonths()plusDays()plusHours()plusMinutes()plusSeconds()plusNanos()minusYears()minusMonths()minusDays()minusHours()minusMinutes()minusSeconds()minusNanos()
以下举一个例子:
LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime localDateTime1 = localDateTime.plusYears(3);
LocalDateTime localDateTime2 = localDateTime.minusYears(3);- 第一行新建一个LocalDateTime实例表示当前这个时间。
- 第二行新建了一个LocalDateTime实例表示三年后。
- 第三行也新建了一个LocalDateTime实例表示三小时前。
ZonedDateTime类是Java 8中日期时间功能里,用于表示带时区的日期与时间信息的类。可以用于表示一个真实事件的开始时间,如某火箭升空时间等等。
ZonedDateTime 类的值是不可变的,所以其计算方法会返回一个新的ZonedDateTime 实例。
创建一个ZonedDateTime实例
有多种方式可以新建ZonedDateTime实例。比如使用当前时间作为值新建对象:
ZonedDateTime dateTime = ZonedDateTime.now();另一种方式是使用指定的年月日、时分秒、纳秒以及时区ID来新建对象:
ZoneId zoneId = ZoneId.of("UTC+1");
ZonedDateTime dateTime2 = ZonedDateTime.of(2015, 11, 30, 23, 45, 59, 1234, zoneId);访问ZonedDateTime对象的时间
你可以通过这些方法访问其日期时间:
getYear()getMonth()getDayOfMonth()getDayOfWeek()getDayOfYear()getHour()getMinute()getSecond()getNano()
这些方法中有一些返回int有一些返回枚举类型,但可以通过枚举类型中的getValue()方法来获得int值。
ZonedDateTime的计算
ZonedDateTime类包含一系列方法,能帮你完成时间计算:
plusYears()plusMonths()plusDays()plusHours()plusMinutes()plusSeconds()plusNanos()minusYears()minusMonths()minusDays()