From 158d9f438c189076a913f28417ed60ea0c62a267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=84=B1=EC=98=81?= Date: Fri, 28 Nov 2025 13:08:47 +0900 Subject: [PATCH] =?UTF-8?q?Date=EA=B4=80=EB=A0=A8=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/자동차과태료_비교로직_정리.md | 22 +++++ .../java/egovframework/util/DateUtil.java | 87 +++++++++++++++++-- .../service/impl/ComparisonServiceImpl.java | 48 ++-------- 3 files changed, 107 insertions(+), 50 deletions(-) diff --git a/docs/자동차과태료_비교로직_정리.md b/docs/자동차과태료_비교로직_정리.md index ae400da..abb4f06 100644 --- a/docs/자동차과태료_비교로직_정리.md +++ b/docs/자동차과태료_비교로직_정리.md @@ -253,3 +253,25 @@ log.info("[이첩][조건1] 법정동코드 불일치! 차량번호: {}, 법정 vhclno, legalDong4, userOrg4); return true; + + +-------- 상품용 로직 완전 변경됨 + +| 1 | 자동차기본정보 | `차량번호`, `부과일자=검사일` | `차대번호`, `소유자명` | +| 2 | 자동차기본정보 | `1.차대번호`, `부과일자=오늘일자` | `차량번호`, `성명`, `민원인주민번호`, `민원인법정동코드` | +| 3 | 자동차등록원본(갑) | `2.차량번호`, `2.성명`, `2.민원인주민번호`, `2.민원인법정동코드` | 갑부 상세 List | +| 4 | 자동차기본정보 | `로직5번.차대번호`, `부과일자=로직5번.CHG_YMD` | `차량번호`, `성명`, `민원인주민번호`, `민원인법정동코드` | + +// 로직 1: 소유자명에 '상품용' 포함 여부 + api-1번호출.소유자명.contains("상품용") +// 2. record.CHG_YMD <= TB_CAR_FFNLG_TRGT.검사종료일자 +// 3. && record.CHG_YMD 가장 마지막 일자, , 검사일 이전일자 중 가장 마지막 명의이전 record +// 4. && record.CHANGE_JOB_SE_CODE == "11" // 명의이전 +// 5. 2~4조건에 맞는 CHG_YMD, 차대번호 가져와 +// 6. 2~4조건에 맞는 CHG_YMD, 차대번호 정보를 가지고 -> 기본사항 조회 api 호출 +// 7. if(소유자명 == 첫번째 검사일기준 자동차기본정보 조회의 소유자명){ + if (r2~4조건에 맞는 CHG_YMD >= TB_CAR_FFNLG_TRGT.유효기간만료일 + && 2~4조건에 맞는 CHG_YMD <= TB_CAR_FFNLG_TRGT.검사종료일자) + return true; + } +} \ No newline at end of file diff --git a/src/main/java/egovframework/util/DateUtil.java b/src/main/java/egovframework/util/DateUtil.java index 7343d3b..16eba6a 100644 --- a/src/main/java/egovframework/util/DateUtil.java +++ b/src/main/java/egovframework/util/DateUtil.java @@ -153,6 +153,34 @@ public class DateUtil { } } + /** + * 날짜 문자열을 LocalDate로 자동 변환 + * 8자리면 yyyyMMdd, 10자리면 yyyy-MM-dd 형식으로 자동 처리 + * + * @param dateStr 날짜 문자열 + * @return LocalDate 객체, 변환 실패 시 null 반환 + */ + public static LocalDate parseDate(String dateStr) { + if (dateStr == null) { + return null; + } + + try { + String trimmed = dateStr.trim(); + if (trimmed.length() == 8) { + // yyyyMMdd 형식 + return LocalDate.parse(trimmed, DateTimeFormatter.ofPattern("yyyyMMdd")); + } else if (trimmed.length() == 10) { + // yyyy-MM-dd 형식 + return LocalDate.parse(trimmed, DateTimeFormatter.ofPattern("yyyy-MM-dd")); + } else { + return null; + } + } catch (Exception e) { + return null; + } + } + /** * 문자열을 LocalDateTime 객체로 변환 * @param dateTimeStr 날짜 시간 문자열 @@ -171,20 +199,32 @@ public class DateUtil { } /** - * yyyyMMdd 형식의 날짜 문자열을 yyyy-MM-dd 형식으로 변환 - * @param dateStr 날짜 문자열 (yyyyMMdd 형식, 예: "20250825") - * @return 변환된 날짜 문자열 (yyyy-MM-dd 형식, 예: "2025-08-25"), 변환 실패 시 null 반환 + * 날짜 문자열을 yyyy-MM-dd 형식으로 변환 + * 8자리면 yyyyMMdd에서 변환, 10자리면 이미 yyyy-MM-dd 형식으로 간주하고 그대로 반환 + * + * @param dateStr 날짜 문자열 (yyyyMMdd 또는 yyyy-MM-dd 형식) + * @return yyyy-MM-dd 형식의 날짜 문자열, 변환 실패 시 원본 문자열 반환 */ public static String formatDateString(String dateStr) { - if (dateStr == null || dateStr.length() != 8) { - return null; + if (dateStr == null || dateStr.isEmpty()) { + return dateStr; } + try { - // yyyyMMdd 형식으로 파싱한 후 yyyy-MM-dd 형식으로 포맷 - LocalDate date = LocalDate.parse(dateStr, DateTimeFormatter.ofPattern("yyyyMMdd")); - return date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); + String trimmed = dateStr.trim(); + if (trimmed.length() == 8) { + // yyyyMMdd → yyyy-MM-dd + LocalDate date = LocalDate.parse(trimmed, DateTimeFormatter.ofPattern("yyyyMMdd")); + return date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); + } else if (trimmed.length() == 10) { + // 이미 yyyy-MM-dd 형식 + return trimmed; + } else { + // 그 외 형식은 그대로 반환 + return dateStr; + } } catch (Exception e) { - return null; + return dateStr; } } @@ -326,6 +366,35 @@ public class DateUtil { return result.format(DateTimeFormatter.ofPattern(pattern)); } + /** + * 날짜가 범위 내에 있는지 확인 + * 날짜 문자열은 yyyyMMdd 또는 yyyy-MM-dd 형식 모두 지원 + * + * @param targetDate 확인할 날짜 문자열 + * @param startDate 시작일 문자열 + * @param endDate 종료일 문자열 + * @return 범위 내 여부 (startDate <= targetDate <= endDate) + */ + public static boolean isDateBetween(String targetDate, String startDate, String endDate) { + if (targetDate == null || startDate == null || endDate == null) { + return false; + } + + try { + LocalDate target = parseDate(targetDate); + LocalDate start = parseDate(startDate); + LocalDate end = parseDate(endDate); + + if (target == null || start == null || end == null) { + return false; + } + + return !target.isBefore(start) && !target.isAfter(end); + } catch (Exception e) { + return false; + } + } + /** * 두 날짜 사이의 일수 계산 * @param startDate 시작 날짜 diff --git a/src/main/java/go/kr/project/carInspectionPenalty/registration/service/impl/ComparisonServiceImpl.java b/src/main/java/go/kr/project/carInspectionPenalty/registration/service/impl/ComparisonServiceImpl.java index fd084b4..6b05957 100644 --- a/src/main/java/go/kr/project/carInspectionPenalty/registration/service/impl/ComparisonServiceImpl.java +++ b/src/main/java/go/kr/project/carInspectionPenalty/registration/service/impl/ComparisonServiceImpl.java @@ -2,6 +2,7 @@ package go.kr.project.carInspectionPenalty.registration.service.impl; import egovframework.constant.TaskPrcsSttsConstants; import egovframework.exception.MessageException; +import egovframework.util.DateUtil; import egovframework.util.SessionUtil; import go.kr.project.api.model.request.NewBasicRequest; import go.kr.project.api.model.request.NewLedgerRequest; @@ -191,7 +192,7 @@ public class ComparisonServiceImpl extends EgovAbstractServiceImpl implements Co // 명의이전 코드 11 확인 및 기간 확인 if ("11".equals(chgTaskSeCd) && chgYmd != null) { - if (isDateBetween(chgYmd, vldPrdExpryYmd, inspEndYmd)) { + if (DateUtil.isDateBetween(chgYmd, vldPrdExpryYmd, inspEndYmd)) { log.info("[상품용] 조건 충족! 차량번호: {}, 변경일자: {}, 변경업무: {}", vhclno, chgYmd, chgTaskSeCd); // 비고 생성 - 갑부 상세 정보 포함 @@ -265,7 +266,7 @@ public class ComparisonServiceImpl extends EgovAbstractServiceImpl implements Co if (daycnt > 115) { // 이첩-2: 부과기준일 = 검사종료일자 + 115일 String inspEndYmd = existingData.getInspEndYmd(); - LocalDate inspEndDate = LocalDate.parse(inspEndYmd, DATE_FORMATTER); + LocalDate inspEndDate = DateUtil.parseDate(inspEndYmd); LocalDate levyCrtrDate = inspEndDate.plusDays(115); levyCrtrYmd = levyCrtrDate.format(DATE_FORMATTER); transferType = "이첩-2"; @@ -428,31 +429,6 @@ public class ComparisonServiceImpl extends EgovAbstractServiceImpl implements Co return request; } - /** - * 날짜가 범위 내에 있는지 확인 - * - * @param targetDate 확인할 날짜 - * @param startDate 시작일 - * @param endDate 종료일 - * @return 범위 내 여부 - */ - private boolean isDateBetween(String targetDate, String startDate, String endDate) { - if (targetDate == null || startDate == null || endDate == null) { - return false; - } - - try { - LocalDate target = LocalDate.parse(targetDate, DATE_FORMATTER); - LocalDate start = LocalDate.parse(startDate, DATE_FORMATTER); - LocalDate end = LocalDate.parse(endDate, DATE_FORMATTER); - - return !target.isBefore(start) && !target.isAfter(end); - } catch (Exception e) { - log.error("날짜 비교 중 오류 발생 - target: {}, start: {}, end: {}", targetDate, startDate, endDate, e); - return false; - } - } - /** * 상품용 비고 생성 * @@ -491,7 +467,7 @@ public class ComparisonServiceImpl extends EgovAbstractServiceImpl implements Co // 3. 갑부 상세 정보 (명의이전 이력) sb.append("\n■ 갑부 상세 (명의이전 이력)\n"); - sb.append(" - 변경일자: ").append(formatDateWithHyphen(ledgerRecord.getChgYmd())).append("\n"); + sb.append(" - 변경일자: ").append(DateUtil.formatDateString(ledgerRecord.getChgYmd())).append("\n"); sb.append(" - 변경업무코드: ").append(nvl(ledgerRecord.getChgTaskSeCd())).append("\n"); sb.append(" - 변경업무명: ").append(nvl(ledgerRecord.getChgTaskSeNm())).append("\n"); sb.append(" - 접수번호: ").append(nvl(ledgerRecord.getAplyRcptNo())).append("\n"); @@ -504,8 +480,8 @@ public class ComparisonServiceImpl extends EgovAbstractServiceImpl implements Co // 4. 비교 기간 sb.append("\n■ 비교 기간\n"); - sb.append(" - 유효기간만료일: ").append(formatDateWithHyphen(vldPrdExpryYmd)).append("\n"); - sb.append(" - 검사종료일자: ").append(formatDateWithHyphen(inspEndYmd)).append("\n"); + sb.append(" - 유효기간만료일: ").append(DateUtil.formatDateString(vldPrdExpryYmd)).append("\n"); + sb.append(" - 검사종료일자: ").append(DateUtil.formatDateString(inspEndYmd)).append("\n"); sb.append(" - 판정: 명의이전일자가 기간 내 존재"); return sb.toString(); @@ -529,16 +505,6 @@ public class ComparisonServiceImpl extends EgovAbstractServiceImpl implements Co return front + "*******"; } - /** - * 날짜 형식 변환 (YYYYMMDD → YYYY-MM-DD) - */ - private String formatDateWithHyphen(String date) { - if (date == null || date.isEmpty() || date.length() != 8) { - return date != null ? date : ""; - } - return date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6, 8); - } - /** * 등록원부 갑부 레코드 상세 정보 생성 */ @@ -552,7 +518,7 @@ public class ComparisonServiceImpl extends EgovAbstractServiceImpl implements Co // 변경 정보 appendIfNotEmpty(detail, "변경업무구분코드", record.getChgTaskSeCd()); appendIfNotEmpty(detail, "변경업무구분명", record.getChgTaskSeNm()); - appendIfNotEmpty(detail, "변경일자", formatDateWithHyphen(record.getChgYmd())); + appendIfNotEmpty(detail, "변경일자", DateUtil.formatDateString(record.getChgYmd())); // 주요 정보 appendIfNotEmpty(detail, "주요번호", record.getMainNo());