深入学习 Java 8 全新日期时间库 java.time(二)

一、前言

上一篇博文我们了解了 LocalDateLocalTimeLocalDateTime,接下来我们了解另外三个 InstantDurationPeriod

我们的思维习惯上以年月日时分秒的方式来理解日期和时间,但计算机却无法理解,更简单来说他更加容易接受的就是时间戳

二、Instant

java.time.Instant 相当于java.utilDate,表示某个瞬时点,它是以Unix元年时间(传统的设定为UTC时区1970年1月1日午夜时分)开始所经历的秒数进行计算。

标准基准时间(称为“历元或纪元”(Epoch),即 1970 年 1 月 1 日 00:00:00 GMT)

Instant的创建方式与前面提及的Local*类似,只不过其传入的参数是距离Epoch的秒数或纳秒值。且相关的操作方法也极其形似。

Instant.now(); // 2019-08-09T06:12:06.981Z
Instant.ofEpochMilli(2356); // 1970-01-01T00:00:02.356Z

需要特别强调一点, Instant 的设计初衷是为了便于机器使用。它包含的是由秒及纳秒所构成的数字。所以,它无法处理那些我们非常容易理解的时间单位。比如下面这段语句:

int day = Instant.now().get(ChronoField.DAY_OF_MONTH);

它会抛出下面这样的异常:

java.time.temporal.UnsupportedTemporalTypeException: Unsupported field:DayOfMonth

Java 1.8 对Date进行了增强,从而可以实现DateInstant之间的转换:

  • Date.toInstant():将Date转换为Instant
  • Date.from(Instant):将指定的Instant转换为Date

LocalDateTime也提供了相应的方法来实现与Instant之间的转换:

  • static LocalDateTime ofInstant(Instant instant, ZoneId zone):通过指定的Instant和ZoneId来创建LocalDateTime实例,其实也就是根据时间戳和时区来创建。
  • default Instant toInstant(ZoneOffset offset):将此日期时间转换为Instant

三、Duration 和 Period

DurationPeriod 都是用来表示两个时间量之间的差值,不同点在于Duration 是基于时间值,而 Period 是基于日期值。

二者都提供了四种静态工厂方法来创建实例:

  • between:通俗易懂也是最常用的,就是取两个时间量之间的差值
  • from:通过其它DurationPeriod 生成
    • 注意:此处传入的参数是TemporalAmount,其就是DurationPeriod 的共同的接口
  • of:就是通过手动指定差值的参数
  • parse:是通过解析传入的字符串来生成
    • 字符串以可选符号开头,由ASCII负号或正符号表示,然后紧跟字母P
    • Duration 解析的字符串格式为PnDTnHnMn.nS
      • 注意:字母T必须出现在时分秒第一次出现之前,且后面至少得跟着一个
      • 提示:D是为了我们简化书写,其实最终会转化为小时。"P2DT3H4M"“PT51H4M”
    • Period 解析的字符串格式为:PnYnMnD
## Duration解析示例
"PT20.345S" -- parses as "20.345 seconds"
"PT15M"     -- parses as "15 minutes" (where a minute is 60 seconds)
"PT10H"     -- parses as "10 hours" (where an hour is 3600 seconds)
"P2D"       -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
"P2DT3H4M"  -- parses as "2 days, 3 hours and 4 minutes"
"P-6H3M"    -- parses as "-6 hours and +3 minutes"
"-P6H3M"    -- parses as "-6 hours and -3 minutes"
"-P-6H+3M"  -- parses as "+6 hours and -3 minutes"

## Period解析示例
"P2Y"             -- Period.ofYears(2)
"P3M"             -- Period.ofMonths(3)
"P4W"             -- Period.ofWeeks(4)
"P5D"             -- Period.ofDays(5)
"P1Y2M3D"         -- Period.of(1, 2, 3)
"P1Y2M3W4D"       -- Period.of(1, 2, 25)
"P-1Y2M"          -- Period.of(-1, 2, 0)
"-P1Y2M"          -- Period.of(-1, -2, 0)

同样的,类库也为DurationPeriod 提供了相应的**minus*** 、plus*with* 方法来对其进行 增、减 和 修改操作,不仅如此还相对的多出了如下操作:

  • Duration
    • Duration abs():返回具有正长度的此Duration的副本。
    • Duration dividedBy(long divisor):返回此Duration除以指定值的副本。
    • Duration multipliedBy(long multiplicand):返回此Duration乘以标量的副本。
    • Duration negated():返回为否定的此Duration的副本。
  • Period
    • Period negated():返回为否定的此period的副本。
    • Period normalized():返回此期间的副本,该副本具有规范化的年份和月份。

我们也可以通过相关的 get* 方法来获取其相关内容:

Duration d=Duration.parse("P2DT3H4M");
d.get(ChronoUnit.SECONDS);
d.getSeconds();
d.get(ChronoUnit.NANOS);
d.getNano();
Period p=Period.parse("P1Y2M3W4D");
p.get(ChronoUnit.YEARS);
p.getYears();
p.get(ChronoUnit.MONTHS);
p.getMonths();
p.get(ChronoUnit.DAYS);
p.getDays();

其它常用方法:

  • Temporal addTo(Temporal temporal):将此持续时间添加到指定的 Temporal 对象。
  • boolean isNegative():检查DurationPeriod 的几个单位中是否有一个是负数的。
  • boolean isZero():检查DurationPeriod 的几个单位中是否都为0。

赞赏

你可能感兴趣的:(Java)