1.属性符号

可以使用Groovy的属性表示法调用TemporalAccessor类型(例如LocalDateLocalTimeZonedDateTime等)的[getLong(TemporalField)](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/TemporalAccessor.html#getLong-java.time.temporal.TemporalField-)方法和TemporalAmount类型(即PeriodDuration)的[get(TemporalUnit)](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/TemporalAmount.html#get-java.time.temporal.TemporalUnit-) 方法。例如:

  1. def date = LocalDate.of(2018, Month.MARCH, 12)
  2. assert date[ChronoField.YEAR] == 2018
  3. assert date[ChronoField.MONTH_OF_YEAR] == Month.MARCH.value
  4. assert date[ChronoField.DAY_OF_MONTH] == 12
  5. assert date[ChronoField.DAY_OF_WEEK] == DayOfWeek.MONDAY.value
  6. def period = Period.ofYears(2).withMonths(4).withDays(6)
  7. assert period[ChronoUnit.YEARS] == 2
  8. assert period[ChronoUnit.MONTHS] == 4
  9. assert period[ChronoUnit.DAYS] == 6

2.范围uptodownto

JSR 310 类型可以与范围运算符一起使用。下面的示例在今天和六天后的LocalDate之间迭代,打印出每个迭代的星期几。由于两个范围边界都包含在内,因此将打印一周中的所有七天。

def start = LocalDate.now()
def end = start + 6 // 6 days later
(start..end).each { date ->
    println date.dayOfWeek
}

upto方法将实现与上述示例中的范围相同的效果。upto方法从较早的start值(包括)迭代到较晚的end值(也包括),每次迭代用递增的下一个值调用一次闭包。

def start = LocalDate.now()
def end = start + 6 // 6 days later
start.upto(end) { next ->
    println next.dayOfWeek
}

downto方法以相反的方向进行迭代,从较晚的start值到较早的end值。
uptodownto和范围的迭代单位与加法和减法的单位相同:LocalDate一次迭代一天,YearMonth一次迭代一个月,Year一年,其他的都是1秒。这两种方法还支持一个可选的TemporalUnit 参数来更改迭代单元。
考虑以下示例,其中2018年3月1日使用的迭代单位迭代至2018年3月2日。

def start = LocalDate.of(2018, Month.MARCH, 1)
def end = start + 1 // 1 day later

int iterationCount = 0
start.upto(end, ChronoUnit.MONTHS) { next ->
    println next
    ++iterationCount
}

assert iterationCount == 1

由于start日期包含在内,因此使用next日期值3月1日来调用结束。然后,upto方法将日期增加一个月,得到日期4月1日。由于该日期在3月2日的指定end日期之后,迭代立即停止,只调用了一次闭包。这种行为与downto方法相同,只是当next的值早于目标结束日期时,迭代就会停止。
简而言之,当使用自定义迭代单元进行uptodownto方法迭代时,迭代的当前值永远不会超过结束值。

3.组合日期时间值

左移运算符 ( <<) 可用于将两个 JSR 310 类型组合成一个聚合类型。例如,可以将 LocalDate 左移到 LocalTime以生成复合 LocalDateTime实例。

MonthDay monthDay = Month.JUNE << 3 // June 3rd
LocalDate date = monthDay << Year.of(2015) // 3-Jun-2015
LocalDateTime dateTime = date << LocalTime.NOON // 3-Jun-2015 @ 12pm
OffsetDateTime offsetDateTime = dateTime << ZoneOffset.ofHours(-5) // 3-Jun-2015 @ 12pm UTC-5

左移运算符是自反的;操作数的顺序无关紧要。

def year = Year.of(2000)
def month = Month.DECEMBER

YearMonth a = year << month
YearMonth b = month << year
assert a == b

4.创建期间和持续时间

右移运算符 ( >>) 生成一个值,表示操作数之间的周期或持续时间。对于ChronoLocalDateYearMonthYear,运算符产生一个Period实例:

def newYears = LocalDate.of(2018, Month.JANUARY, 1)
def aprilFools = LocalDate.of(2018, Month.APRIL, 1)

def period = newYears >> aprilFools
assert period instanceof Period
assert period.months == 3

运算符为时间感知 JSR 类型生成一个Duration

def duration = LocalTime.NOON >> (LocalTime.NOON + 30)
assert duration instanceof Duration
assert duration.seconds == 30

如果运算符左侧的值早于右侧的值,则结果为正。如果左侧晚于右侧,则结果是否定的:

def decade = Year.of(2010) >> Year.of(2000)
assert decade.years == -10