Youssef Gamal
Youssef Gamal

Reputation: 23

How to Validate Collection of Date with Specific Format In Spring Boot

I'm using spring data validation and i want to validate Set or List of Date but all the examples that i saw before were validating single value, Here is request class representation

CircuitJurisdictionRequest.java

package eg.intercom.ppo.revamp.model.to.request;

import com.fasterxml.jackson.annotation.JsonFormat;
import eg.intercom.ppo.revamp.model.enums.AppliedLawEnum;
import eg.intercom.ppo.revamp.model.enums.TimeStatusEnum;
import eg.intercom.ppo.revamp.model.to.RequestActivationStatus;
import jakarta.validation.constraints.*;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDate;
import java.util.Date;
import java.util.Set;

@Data
@NoArgsConstructor
public class CircuitJurisdictionRequest {
    @NotNull(message = "Circuit ID is required")
    @Positive(message = "Circuit ID Must Be >= 1")
    private Long circuitId;

    @NotNull(message = "Table type ID is required")
    @Positive(message = "Table type ID Must Be >= 1")
    private Long tableTypeId;

    @NotNull(message = "Court room ID is required")
    @Positive(message = "Court room ID Must Be >= 1")
    private Long courtRoomId;

    @NotNull(message = "Applied law is required")
    private AppliedLawEnum appliedLaw;

    @NotNull(message = "Time status is required")
    private TimeStatusEnum timeStatus;

    @Size(max = 10, message = "Session day should not exceed 10 characters")
    @Pattern(
            regexp = "^(SUNDAY|MONDAY|TUESDAY|WEDNESDAY|THURSDAY|FRIDAY|SATURDAY)$",
            message = "Session day must be a valid day of the week (e.g., SUNDAY, MONDAY, etc.)"
    )
    private String sessionDay;
    
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
    private Set<@NotNull(message = "Each date in Session Scheduler must not be null") Date> sessionScheduler;

    @NotNull(message = "new Cases Capacity is required")
    @Min(value = 0, message = "New cases capacity must be zero or positive")
    @Max(value = 1000, message = "New cases capacity should not exceed 1000")
    private Integer newCasesCapacity;

    @NotNull(message = "postponed Cases Capacity is required")
    @Min(value = 0, message = "Postponed cases capacity must be zero or positive")
    @Max(value = 1000, message = "Postponed cases capacity should not exceed 1000")
    private Integer postponedCasesCapacity;

    @NotNull(message = "first Session Date is required")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
    private LocalDate firstSessionDate; // Optionally add @Future or @NotNull if required

    @NotEmpty(message = "At least one digital Jurisdiction is required")
    private Set<@Min(value = 0, message = "Digital Jurisdiction Must be >= 0")
    @Max(value = 9, message = "Digital Jurisdiction Must be <= 9") Integer> digitalJurisdiction;

    private RequestActivationStatus activationStatus;
}


What i Want

i want to validate all dates into sessionScheduler to be sent in the request as json string with format dd-MM-yyyy

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
    private Set<@NotNull(message = "Each date in Session Scheduler must not be null") Date> sessionScheduler;

Upvotes: 0

Views: 38

Answers (2)

Youssef Gamal
Youssef Gamal

Reputation: 23

The Following Works Correctly for me and the following info is

1- @JsonFormat check over each element of the Collection to be in the format dd-MM-yyyy

2- added @Future to check that sent date into the future


    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy") // to ensure that the date format sent in dd-MM-yyyy
    private Set<@NotNull(message = "Each date in Session Scheduler must not be null")
                @Future(message = "Each Session Scheduler Date must be In Future") LocalDate> sessionScheduler;

Upvotes: 1

To validate a collection of dates with a specific format (dd-MM-yyyy) in Spring Boot, you'll need to combine @JsonFormat for date deserialization and a custom validator to ensure each date follows the desired format

1 ) Define ValidDateFormat Annoation for Validation

import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.*;

@Documented
@Constraint(validatedBy = DateFormatValidator.class)
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidDateFormat {
    String message() default "Invalid date format. Expected format is dd-MM-yyyy";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    String pattern() default "dd-MM-yyyy";
}

2 ) Define DateFormatValidator

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;

public class DateFormatValidator implements ConstraintValidator<ValidDateFormat, Set<Date>> {
    private String pattern;

    @Override
    public void initialize(ValidDateFormat constraintAnnotation) {
        this.pattern = constraintAnnotation.pattern();
    }

    @Override
    public boolean isValid(Set<Date> dates, ConstraintValidatorContext context) {
        if (dates == null || dates.isEmpty()) {
            return true; // @NotNull/@NotEmpty will handle null/empty cases
        }

        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        sdf.setLenient(false);

        for (Date date : dates) {
            try {
                String formattedDate = sdf.format(date);
                sdf.parse(formattedDate);
            } catch (ParseException e) {
                return false;
            }
        }
        return true;
    }
}

3 ) Apply the Validator to sessionScheduler

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
@ValidDateFormat(message = "Each date must follow the format dd-MM-yyyy")
private Set<@NotNull(message = "Each date in Session Scheduler must not be null") Date> sessionScheduler;

Upvotes: 1

Related Questions