diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 87f81625..eb17503f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -57,6 +57,7 @@ import java.text.ParseException; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.*; @@ -1704,15 +1705,44 @@ public class ApplicationDao { private void applyDateFilter(Path fieldPath, CriteriaBuilder criteriaBuilder, List predicates, Object value, MatchModeEnum matchMode, Root root) { if (fieldPath.getJavaType().equals(LocalDateTime.class)) { - LocalDateTime testDateTime = DateTimeUtil.parseStringToLocalDateTime(value.toString()); + // Convert input string: Replace 'T' with space + String formattedValue = value.toString().replace("T", " "); + + // Handle timezones and UTC (`Z` or `+HH:mm`) + if (formattedValue.contains("Z") || formattedValue.matches(".*[+-]\\d{2}:\\d{2}$")) { + OffsetDateTime offsetDateTime = OffsetDateTime.parse(value.toString(), DateTimeFormatter.ISO_OFFSET_DATE_TIME); + formattedValue = offsetDateTime.toLocalDateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")); + } + + // Check if more than 3 decimal places exist + if (formattedValue.contains(".")) { + int dotIndex = formattedValue.indexOf("."); + if (formattedValue.length() > dotIndex + 4) { + formattedValue = formattedValue.substring(0, dotIndex + 4); // Keep only 3 decimals + } + } else { + formattedValue += ".000"; // Ensure 3 decimals + } + + // Define correct date-time format + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); + + // Parse the formatted value into LocalDateTime + LocalDateTime dateTimeValue = LocalDateTime.parse(formattedValue, formatter); + + // Extract only the date portion + LocalDate dateValue = dateTimeValue.toLocalDate(); + + // Convert database field to LocalDate for date-only comparison + Expression dateField = criteriaBuilder.function("DATE", LocalDate.class, fieldPath); + MatchModeEnum mode = MatchModeEnum.fromObject(matchMode.getValue()); - switch (mode) { -// case DATEIS -> predicates.add(criteriaBuilder.equal(fieldPath.as(Timestamp.class), Timestamp.valueOf(testDateTime))); - case DATEISNOT -> predicates.add(criteriaBuilder.notEqual(fieldPath.as(Timestamp.class), Timestamp.valueOf(testDateTime))); - case BEFORE -> predicates.add(criteriaBuilder.lessThan(fieldPath.as(Timestamp.class), Timestamp.valueOf(testDateTime))); - case AFTER -> predicates.add(criteriaBuilder.greaterThan(fieldPath.as(Timestamp.class), Timestamp.valueOf(testDateTime))); + case DATEIS -> predicates.add(criteriaBuilder.equal(dateField, dateValue)); + case DATEISNOT -> predicates.add(criteriaBuilder.notEqual(dateField, dateValue)); + case BEFORE -> predicates.add(criteriaBuilder.lessThan(fieldPath.as(Timestamp.class), Timestamp.valueOf(dateTimeValue))); + case AFTER -> predicates.add(criteriaBuilder.greaterThan(fieldPath.as(Timestamp.class), Timestamp.valueOf(dateTimeValue))); } } }