与等效的日历代码相比,结果 java.time 代码是否具有更多代码语句

Is resultant java.time code has more code statements compared to equivalent Calendar code

最近,我尝试将我们的一个旧代码库从 Calendar 移植到 java.time,因为我们需要相当多的算术功能,而这些功能只能在 java.time 中找到].

如果我们在当前代码库中使用Calendar,我们需要执行大量来回转换(从CalendarInstant,从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;

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 的端口有什么可以改进的地方吗?

由于您希望在给定时区的时间之间进行日期操作,因此不应使用毫秒或 LocalDateTime,而应使用 ZonedDateTime。我认为您的 List 应该包含 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 而不是 longs,则不需要所有 Instant.ofEpochMilli()toEpochMilli() 调用。