p; .appendText(ChronoField.MONTH_OF_YEAR)
.appendText(ChronoField.DAY_OF_MONTH)
.appendLiteral("号")
.parseCaseInsensitive().toFormatter(Locale.CHINA);
处理不同的时区和历法
之前所看到的日期和时间种类都不包含时区信息。时区的处理是新版日期和时间API新增加的重要功能,新的 java.time.ZoneId 类是老版 java.util.TimeZone 的替代品。
时区是按照一定的规则将区域划分成的标准时间相同的区间。在ZoneRules这个类中包含了40个这样的实例。你可以使用ZoneId的getRules()得到指定时区的规则。每个特定的ZoneId对象都由一个地区标识:
ZoneId romeZone = ZoneId.of("Europe/Rome"); //格式 欧洲/罗马
地区ID都为 “{区域}/{城市}”的格式,这些地区集合的设定都由英特网编号分配机构(IANA)的时区数据库提供。你可以通过java 8的新方法toZoneId将一个老的时区对象转换为ZoneId
ZoneId zoneId = TimeZone.getDefault().toZoneId();
一旦得到一个ZoneId对象,就可以将它与LocalDate、LocalDateTIme或者是Instant对象整合起来,构造为一个ZonedDateTime实例,它代表了相对于指定时区的时间点,
LocalDate date = LocalDate.of(2018,8,22);
ZonedDateTime zdt1 = date.atStartOfDay(romeZone);
LocalDateTime dateTime = LocalDateTime.of(2018,8,23,13,48,00);
ZonedDateTime zdt2 = dateTime.atZone(romeZone);
Instant instant = Instant.now();
ZonedDateTime zdt3 = instant.atZone(romeZone);
ZonedDateTime = LocalDateTime(LocalDate + LocalTime) + ZoneId
通过ZoneId,你还可以将LocalDateTime转换为Instant
LocalDateTime dateTime = LocalDateTime.of(2018,8,23,13,48,00);
Instant instantFromDateTime = dateTime.toInstant(romeZone);
Instant instant1 = Instant.now();
LocalDateTime timeFromInstant = LocalDateTime.ofInstant(romeZone);
利用和 UTC/格林尼治时间的固定偏差计算时区
另一种比较常用的表达时区的方式就是利用当前时区和 UTC/格林尼治 的固定偏差,比如,纽约落后伦敦5小时。这种情况下,你可以使用ZoneOffset类,它是ZoneId的一个子类,表示的是当前时间和伦敦格林尼治子午时间的差异:
ZoneOffset newYorkOffset = ZoneOffset.of("-05:00");
这种方式不推荐使用,因为 -05:00 的偏差实际上是对应的美国东部标准时间,并未考虑任何日光时的影响。
LocalDateTime dateTime1 = LocalDateTime.now();
OffsetDateTime dateTimeInNewYork1 = OffsetDateTime.of(dateTime1,newYorkOffset);
它使用ISO-8601的历法系统,以相对于UTC时间的偏差方式表示日期时间。
使用别的日历系统
ISO-8601日历系统是世界文明日历系统的事实标准。但是,java 8 中另外提供了4种其他的日历系统。这些日历系统中的每一个都有一个对应的日志类,分别是ThaiBuddhistDate、MinguoDate、JapaneseDate以及HijrahDate。所有这些类以及LocalDate都实现了ChronoLocalDate接口,能够对公历的日期进行建模。利用LocalDate对象,可以创建这些类的实例。
小结:
1、Java 8之前的java.util.Date类以及其他用于建模日期时间的雷有很多不一致及设计上的缺陷,包括易变性以及糟糕的偏移值、默认值和命名。
2、新版的日期和时间API中,日期-时间对象是不可变的。
3、新的API提供了两种不同的时间表示方式,有效地区分了运行时人喝机器的不同需求。
4、操纵的日期不会影响老值,而是新生成一个实例。
5、TemporalAdjuster可以更精确的操纵日期,还可以自定义日期转换器。
6、他们都是线程安全的