1. API的易用性
- LocalDate 提供了丰富的日期操作方法,如 plusDays, minusDays,
- withDayOfMonth 等。
- Date 的 API 设计较为复杂,且存在许多过时的方法。
2. 线程安全性
- Date 不是线程安全的,多个线程同时操作 Date 对象可能会导致不一致或错误。
- LocalDate 是不可变的(immutable),并且是线程安全的。
3. 暂举以上两点吧,下面给出示例
功能描述:
给这个方法实现一个逻辑。根据查询条件currentDate和taskType以及userId和TenantId查询task表符合条件的所有数据。之后再根据startTime和endTime判断并标记出来每一天是否有任务
@Override
public BaseResultEntity findTaskDayStatusByCurrentDate(TaskListRequest taskRequest) {
log.info("findTaskDayStatusByCurrentDate{}", JSONObject.toJSONString(taskRequest));
// 获取当前日期
LocalDate currentDate = LocalDate.now();
if (taskRequest.getCurrentDate() != null) {
ZoneId zone = ZoneId.systemDefault();
currentDate = taskRequest.getCurrentDate().toInstant().atZone(zone).toLocalDate();
}
// 获取本月的开始和结束日期
LocalDate firstDayOfMonth = currentDate.withDayOfMonth(1);
LocalDate lastDayOfMonth = currentDate.withDayOfMonth(currentDate.lengthOfMonth());
// 构建查询条件
Query query = new Query();
query.addCriteria(Criteria.where("userId").is(taskRequest.getUserId()));
query.addCriteria(Criteria.where("tenantId").is(taskRequest.getTenantId()));
if (ObjectUtil.isNotEmpty(taskRequest.getTaskType())) {
query.addCriteria(Criteria.where("taskType").is(taskRequest.getTaskType()));
}
query.addCriteria(Criteria.where("startTime").lte(Date.from(lastDayOfMonth.atTime(LocalTime.MAX).atZone(zone).toInstant())));
query.addCriteria(Criteria.where("endTime").gte(Date.from(firstDayOfMonth.atStartOfDay().atZone(zone).toInstant())));
// 获取符合条件的任务
List<Task> tasks = mongoTemplate.find(query, Task.class);
// 初始化每一天的状态为 false
List<DailyTaskStatusDTO> dailyStatusList = new ArrayList<>();
for (LocalDate date = firstDayOfMonth; !date.isAfter(lastDayOfMonth); date = date.plusDays(1)) {
DailyTaskStatusDTO dailyStatus = new DailyTaskStatusDTO();
dailyStatus.setDate(Date.from(date.atStartOfDay().atZone(zone).toInstant()));
dailyStatus.setHasTask(false);
dailyStatusList.add(dailyStatus);
}
// 遍历任务,标记每一天是否有任务
for (Task task : tasks) {
LocalDate taskStartDate = task.getStartTime().toInstant().atZone(zone).toLocalDate();
LocalDate taskEndDate = task.getEndTime().toInstant().atZone(zone).toLocalDate();
for (LocalDate date = taskStartDate; !date.isAfter(taskEndDate); date = date.plusDays(1)) {
for (DailyTaskStatusDTO dailyStatus : dailyStatusList) {
if (DateUtil.isSameDay(dailyStatus.getDate(), Date.from(date.atStartOfDay().atZone(zone).toInstant()))) {
dailyStatus.setHasTask(true);
}
}
}
}
return new SuccessResultEntity(dailyStatusList);
}