最近,我尝试将我们的旧代码库之一从Calendar
移植到java.time
,因为我们需要大量的算术功能,这些功能只能在java.time
中找到。
如果我们在当前代码库中使用Calendar
,则需要来回进行大量转换(从Calendar
到Instant
,从Instant
返回Calendar
),在我们的代码中间。
为避免此类麻烦的转换,我们决定取消使用Calendar
,并将其移植到等效的java.time
代码。
我对港口有点怀疑。与日历代码相比,
// reminderCal is Calendar object.
long startTimestamp = getStartTimestamp();
reminderCal.setTimeInMillis(startTimestamp);
while (startTimestamp <= maxTimestamp) {
resultList.add(startTimestamp);
reminderCal.add(Calendar.DAY_OF_MONTH, 1);
startTimestamp = reminderCal.getTimeInMillis();
}
return resultList;
// Epoch timestamp loopTs as initial input.
long startTimestamp = getStartTimestamp();
final ZoneId zoneId = ZoneId.systemDefault();
while (startTimestamp <= maxTimestamp) {
resultList.add(startTimestamp);
// More code, more temporary instances required compared
// with Calendar's version. Not sure we're doing the right
// way.
Instant instant = Instant.ofEpochMilli(startTimestamp);
LocalDateTime time = LocalDateTime.ofInstant(instant, zoneId);
time = time.plus(1, ChronoUnit.DAYS);
startTimestamp = time.atZone(zoneId).toInstant().toEpochMilli();
}
return resultList;
对于上面的代码,我想知道,我们是否正确地进行了端口优化? java.time
的端口上还有什么可以改善的地方?
答案 0 :(得分:4)
由于您希望在给定时区中的时间之间进行日期操作,因此您不应使用毫秒或LocalDateTime,而应使用ZonedDateTime。而且我认为您的列表应该包含Instants而不是longs,但是现在让我们保持这种状态:
long startTimestamp = getStartTimestamp();
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime maxDateTime = Instant.ofEpochMilli(maxTimestamp).atZone(zoneId);
ZonedDateTime loopDateTime = Instant.ofEpochMilli(loopTs).atZone(zoneId);
while (!loopDateTime.isAfter(maxDateTime)) {
tsList.add(loopDateTime.toInstant().toEpochMilli());
loopDateTime = loopDateTime.plusDays(1);
}
这更简洁,但也更具可读性。如果您使用Instants而不是long进行操作,则不需要所有Instant.ofEpochMilli()
和toEpochMilli()
调用。