尽管java.util
包中存在Date
、Calendar
和TimeZone
类型的缺点。它们在Java API中相当常见(至少在Java 8之前的API中是如此)。为了适应这种API的使用,Groovy提供了在JSR 310类型和遗留类型之间转换的方法。
大多数JSR类型都配备了toDate()
和toCalendar()
方法,用于转换为相对等效的java.util.Date
和java.util.Calendar
的值。ZoneId
和ZoneOffset
都提供了一个toTimeZone()
方法来转换为java.util.TimeZone
。
// LocalDate to java.util.Date
def valentines = LocalDate.of(2018, Month.FEBRUARY, 14)
assert valentines.toDate().format('MMMM dd, yyyy') == 'February 14, 2018'
// LocalTime to java.util.Date
def noon = LocalTime.of(12, 0, 0)
assert noon.toDate().format('HH:mm:ss') == '12:00:00'
// ZoneId to java.util.TimeZone
def newYork = ZoneId.of('America/New_York')
assert newYork.toTimeZone() == TimeZone.getTimeZone('America/New_York')
// ZonedDateTime to java.util.Calendar
def valAtNoonInNY = ZonedDateTime.of(valentines, noon, newYork)
assert valAtNoonInNY.toCalendar().getTimeZone().toZoneId() == newYork
请注意,在转换为旧类型时:
- 纳秒值被截断为毫秒。例如,一个
LocalTime
有ChronoUnit.NANOS
的99999999纳秒的纳秒值转换为999毫秒。 - 转换“本地”类型(
LocalDate
、LocalTime
和LocalDateTime
)时,返回Date
或Calendar
的时区将是系统默认值。 - 转换纯时间类型(
LocalTime
或OffsetTime
)时,Date
或Calendar
的年/月/日设置为当前日期。 - 转换仅日期类型(
LocalDate
)时,Date
或Calendar
的时间值将被清除,即00:00:00.000
。 - 将
OffsetDateTime
转换为Calendar
时,只有ZoneOffset
的小时和分钟传递到相应的TimeZone
。幸运的是,非零秒的区域偏移很少。
Groovy为Date
和Calendar
添加了许多方法,用于转换为各种JSR 310类型:
Date legacy = Date.parse('yyyy-MM-dd HH:mm:ss.SSS', '2010-04-03 10:30:58.999')
assert legacy.toLocalDate() == LocalDate.of(2010, 4, 3)
assert legacy.toLocalTime() == LocalTime.of(10, 30, 58, 999_000_000) // 999M ns = 999ms
assert legacy.toOffsetTime().hour == 10
assert legacy.toYear() == Year.of(2010)
assert legacy.toMonth() == Month.APRIL
assert legacy.toDayOfWeek() == DayOfWeek.SATURDAY
assert legacy.toMonthDay() == MonthDay.of(Month.APRIL, 3)
assert legacy.toYearMonth() == YearMonth.of(2010, Month.APRIL)
assert legacy.toLocalDateTime().year == 2010
assert legacy.toOffsetDateTime().dayOfMonth == 3
assert legacy.toZonedDateTime().zone == ZoneId.systemDefault()