When registering data that has a period by date, I want to avoid duplication with the already registered period. I couldn't find many Java samples using LocalDate, so I will publish it.
There are a total of four patterns with overlapping date periods.
The conditional expression that can cover all patterns is as follows.
Conditional expression
Green.start date<=black.End date&& Green.End date=>black.start date
A sample that can be registered only when the start date and end date are entered from the screen and the input period does not overlap with the existing period (plural).
Model class to be passed to the screen with the start date and end date to be registered and the ID of automatic numbering.
DurationModel.java
package com.tamorieeeen.sample.model;
import java.time.LocalDate;
import org.springframework.format.annotation.DateTimeFormat;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
*
* @author tamorieeeen
*
*/
@Getter
@Setter
@NoArgsConstructor
public class DurationModel {
//Auto when saving_Numbering with increment
private int id;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate startDate;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate endDate;
}
Service class called from Controller.
DurationService.java
package com.tamorieeeen.sample.service;
import java.time.LocalDate;
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.stereotype.Service;
import com.tamorieeeen.sample.model.DurationModel;
/**
*
* @author tamorieeeen
*
*/
@Service
public class DurationService {
/**
*Check if it is already registered
*/
public boolean isInvalid(DurationModel model) {
return this.getDurationList()
.stream()
.filter(u -> model.getId() != u.getId()) // ※1
.anyMatch(u ->
(order.getStartDate().isBefore(u.getEndDate())
&& order.getEndDate().isAfter(u.getStartDate()))
|| order.getStartDate().isEqual(u.getEndDate())
|| order.getEndDate().isEqual(u.getStartDate()));
}
/**
*Get list
*/
private List<DurationModel> getDurationList() {
//TODO Get already registered data
}
/**
*sign up/update
*/
@Transactional
public void saveDuration(DurationModel model) {
//Data storage process in TODO DB etc.
}
}
this.getDurationList ()
when updating the data, so it will be treated as duplicate and will be caught in validation.
If you are only thinking about new registration, this line is unnecessary.Actually, @Validated
and BindingResult
are used for validation check, but that part is omitted.
DurationController.java
/**
*
* @author tamorieeeen
*
*/
@Controller
public class DurationController {
@Autowired
private DurationService durationService;
/**
*sign up
*/
@GetMapping("/duration/register")
public String register(Model model) {
model.addAttribute("duration", new DurationModel());
return "duration/register";
}
/**
*New registration process
*/
@PostMapping("/duration/register")
public String registerComplete(Model model,
@ModelAttribute("duration") DurationModel duration,
RedirectAttributes redirect) {
//Validation check
if (durationService.isInvalid(duration)) {
model.addAttribute("invalid", true);
return "duration/register";
}
durationService.saveDuration(duration);
redirect.addFlashAttribute("complete", true);
return "redirect:/duration/register";
}
}
The html header is common, but it is not relevant this time, so it is omitted.
register.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="common :: meta_header('sample',~{::link},~{::script},~{::meta})">
</head>
<body>
<div th:if="${complete}">
<p>I have registered the period.</p>
</div>
<div th:if="${invalid}">
<p>Registration is not possible because the period is duplicated.</p>
</div>
<form th:action="@{/duration/register}" method="post" th:object="${duration}">
<table>
<tr><td>start date</td><td>
<input type="date" th:field="*{startDate}" th:value="*{startDate}" />
</td></tr>
<tr><td>End date</td><td>
<input type="date" th:field="*{endDate}" th:value="*{endDate}" />
</td></tr>
</table>
<input type="button" th:value="sign up" onclick="submit();" />
</form>
</body>
</html>
Recommended Posts