与等效的日历代码相比,结果 java.time 代码是否具有更多代码语句
Is resultant java.time code has more code statements compared to equivalent Calendar code
最近,我尝试将我们的一个旧代码库从 Calendar
移植到 java.time
,因为我们需要相当多的算术功能,而这些功能只能在 java.time
中找到].
如果我们在当前代码库中使用Calendar
,我们需要执行大量来回转换(从Calendar
到Instant
,从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
的端口有什么可以改进的地方吗?
由于您希望在给定时区的时间之间进行日期操作,因此不应使用毫秒或 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()
调用。
最近,我尝试将我们的一个旧代码库从 Calendar
移植到 java.time
,因为我们需要相当多的算术功能,而这些功能只能在 java.time
中找到].
如果我们在当前代码库中使用Calendar
,我们需要执行大量来回转换(从Calendar
到Instant
,从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
的端口有什么可以改进的地方吗?
由于您希望在给定时区的时间之间进行日期操作,因此不应使用毫秒或 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()
调用。