与等效的Calendar代码相比,结果java.time代码具有更多的代码语句吗?

时间:2018-10-25 05:37:52

标签: java java-time java.util.calendar

最近,我尝试将我们的旧代码库之一从Calendar移植到java.time,因为我们需要大量的算术功能,这些功能只能在java.time中找到。

如果我们在当前代码库中使用Calendar,则需要来回进行大量转换(从CalendarInstant,从Instant返回Calendar),在我们的代码中间。

为避免此类麻烦的转换,我们决定取消使用Calendar,并将其移植到等效的java.time代码。

我对港口有点怀疑。与日历代码相比,

  • 在while循环中创建更多临时对象实例。
  • 需要更多的代码语句。

日历代码

// 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;

java.time代码

// 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的端口上还有什么可以改善的地方?

1 个答案:

答案 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()调用。