[Java] Date period duplication check sample

Overview

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.

environment

Pattern with overlapping periods

There are a total of four patterns with overlapping date periods. Qiita用画像.png

  1. Pattern that the first half wears (including the same end date of ① and green start date)
  2. Pattern that the latter half is covered (including the same start date of ② and green end date)
  3. All-wear pattern (including exactly the same start date and end date)
  4. Partially worn pattern

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

sample

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 with a date period to register

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

Period duplication judgment logic Service class

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.
    }
}

Controller class

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";
    }
}

Screen side html (thymeleaf)

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>

reference

-Check for duplicate dates

Recommended Posts

[Java] Date period duplication check sample
Period duplication check (LocalTime, LocalDate, LocalDateTime)
Java sample code 02
Java version check
Java sample code 03
Selenium sample (Java)
Java GUI sample
Java support period
Java8, 9, 10 support period
Java check process
Java sample code 01
Check Java toString () implementation
[Java] Holiday judgment sample
Java basic date manipulation
[Java] logback slf4j sample
Date manipulation in Java 8
java: Add date [Note]
[Java] Date type conversion
Sample code to parse date and time with Java SimpleDateFormat
Digital signature sample code (JAVA)
Java parallelization code sample collection
Check Java9 Interface private methods
Check https connection in Java
Java standard log output sample
[Java] Date Related Term Memo
Selenium Sample Reservation Form (Java)
View current date in Java