尽管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.Datedef valentines = LocalDate.of(2018, Month.FEBRUARY, 14)assert valentines.toDate().format('MMMM dd, yyyy') == 'February 14, 2018'// LocalTime to java.util.Datedef noon = LocalTime.of(12, 0, 0)assert noon.toDate().format('HH:mm:ss') == '12:00:00'// ZoneId to java.util.TimeZonedef newYork = ZoneId.of('America/New_York')assert newYork.toTimeZone() == TimeZone.getTimeZone('America/New_York')// ZonedDateTime to java.util.Calendardef 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()
